Arm Assembly - 调用具有 4 个以上参数的函数

发布于 2024-12-13 23:53:04 字数 2807 浏览 2 评论 0原文

我知道当调用程序集中的函数时,r0 包含第一个参数,直到 r3 是第四个参数。我知道当它超过四个时,将使用堆栈指针,但我不太确定具体细节。 r0-r3 是否仍然保留前四个,其余的进入堆栈?我正在查看下面的程序集,试图了解它调用 mach_msg (具有七个参数的函数)的作用。在进入此代码时,r0 和 r1 包含两个参数

var_38          = -0x38
var_34          = -0x34
var_30          = -0x30
var_2C          = -0x2C
var_24          = -0x24
var_20          = -0x20
var_18          = -0x18
var_14          = -0x14
var_10          = -0x10
var_C           = -0xC
00001220
00001220                 PUSH            {R7,LR}
00001222                 MOV             R7, SP
00001224                 SUB             SP, SP, #0x30
00001226                 MOV             R2, (_NDR_record_ptr - 0x1232) ; _NDR_record_ptr
0000122E                 ADD             R2, PC ; _NDR_record_ptr
00001230                 LDR             R2, [R2] ; _NDR_record
00001232                 LDR             R3, [R2]
00001234                 LDR             R2, [R2,#4]
00001236                 STR             R2, [SP,#0x38+var_10]
00001238                 MOVS            R2, #0x24 ; '$'
0000123A                 STR             R3, [SP,#0x38+var_14]
0000123C                 MOVS            R3, #0
0000123E                 STRB.W          R1, [SP,#0x38+var_C]
00001242                 MOVS            R1, #0x13
00001244                 STR             R1, [SP,#0x38+var_2C]
00001246                 MOVS            R1, #1
00001248                 STR             R0, [SP,#0x38+var_24]
0000124A                 MOV             R0, 0x1E84EA
00001252                 STR             R3, [SP,#0x38+var_20]
00001254                 STR             R3, [SP,#0x38+var_38]
00001256                 STR             R3, [SP,#0x38+var_34]
00001258                 STR             R0, [SP,#0x38+var_18]
0000125A                 STR             R3, [SP,#0x38+var_30]
0000125C                 ADD             R0, SP, #0x38+var_2C
0000125E                 BLX             _mach_msg
00001262                 ADD             SP, SP, #0x30
00001264                 POP             {R7,PC}

以下是被调用和使用的内容的定义:

typedef struct {
    unsigned char       mig_vers;
    unsigned char       if_vers;
    unsigned char       reserved1;
    unsigned char       mig_encoding;
    unsigned char       int_rep;
    unsigned char       char_rep;
    unsigned char       float_rep;
    unsigned char       reserved2;
} NDR_record_t;
extern NDR_record_t NDR_record;
extern mach_msg_return_t    mach_msg(
                mach_msg_header_t *msg,
                mach_msg_option_t option,
                mach_msg_size_t send_size,
                mach_msg_size_t rcv_size,
                mach_port_name_t rcv_name,
                mach_msg_timeout_t timeout,
                mach_port_name_t notify);

根据我的理解,变量的堆栈指针被反转 48 个字节。 48 个字节是用于额外的 3 个参数还是所有参数?

I know that when calling a function in assembly r0 contains the first argument up to r3 being the fourth. I know that when it goes beyond four the stack pointer is used but I'm not too sure on the specifics. Does r0-r3 still hold the first four and the rest goes on the stack? I'm looking at the following piece of assembly trying to understand what it's doing to call mach_msg (a function with seven arguments). On entry to this code, r0 and r1 contain the two arguments

var_38          = -0x38
var_34          = -0x34
var_30          = -0x30
var_2C          = -0x2C
var_24          = -0x24
var_20          = -0x20
var_18          = -0x18
var_14          = -0x14
var_10          = -0x10
var_C           = -0xC
00001220
00001220                 PUSH            {R7,LR}
00001222                 MOV             R7, SP
00001224                 SUB             SP, SP, #0x30
00001226                 MOV             R2, (_NDR_record_ptr - 0x1232) ; _NDR_record_ptr
0000122E                 ADD             R2, PC ; _NDR_record_ptr
00001230                 LDR             R2, [R2] ; _NDR_record
00001232                 LDR             R3, [R2]
00001234                 LDR             R2, [R2,#4]
00001236                 STR             R2, [SP,#0x38+var_10]
00001238                 MOVS            R2, #0x24 ; '

Here are the definitions for the stuff being called and used:

typedef struct {
    unsigned char       mig_vers;
    unsigned char       if_vers;
    unsigned char       reserved1;
    unsigned char       mig_encoding;
    unsigned char       int_rep;
    unsigned char       char_rep;
    unsigned char       float_rep;
    unsigned char       reserved2;
} NDR_record_t;
extern NDR_record_t NDR_record;
extern mach_msg_return_t    mach_msg(
                mach_msg_header_t *msg,
                mach_msg_option_t option,
                mach_msg_size_t send_size,
                mach_msg_size_t rcv_size,
                mach_port_name_t rcv_name,
                mach_msg_timeout_t timeout,
                mach_port_name_t notify);

From what I understand, the stack pointer is being reversed 48 bytes for variables. Is that 48 bytes for the extra 3 arguments or for all of them?

0000123A STR R3, [SP,#0x38+var_14] 0000123C MOVS R3, #0 0000123E STRB.W R1, [SP,#0x38+var_C] 00001242 MOVS R1, #0x13 00001244 STR R1, [SP,#0x38+var_2C] 00001246 MOVS R1, #1 00001248 STR R0, [SP,#0x38+var_24] 0000124A MOV R0, 0x1E84EA 00001252 STR R3, [SP,#0x38+var_20] 00001254 STR R3, [SP,#0x38+var_38] 00001256 STR R3, [SP,#0x38+var_34] 00001258 STR R0, [SP,#0x38+var_18] 0000125A STR R3, [SP,#0x38+var_30] 0000125C ADD R0, SP, #0x38+var_2C 0000125E BLX _mach_msg 00001262 ADD SP, SP, #0x30 00001264 POP {R7,PC}

Here are the definitions for the stuff being called and used:

From what I understand, the stack pointer is being reversed 48 bytes for variables. Is that 48 bytes for the extra 3 arguments or for all of them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

-小熊_ 2024-12-20 23:53:04

48 个字节中,12 个用于额外的 3 个参数,其余用于局部变量。您可以在代码中看到这一点,其中函数在 r0 到 r3 中传递四个参数,在 [SP,#0x38+var_38] 中传递另一个参数(如果您进行数学计算,则将其解析为 [sp]),在 [sp,#4 中传递另一个参数],最后一个在 [sp,#8] 中。

Of the 48 bytes, 12 are for the extra 3 parameters, and the others are for local variables. You can see this in the code where the function passes four parameters in r0 through r3, another in [SP,#0x38+var_38] (which if you do the math resolves to just [sp]), another in [sp,#4], and the last in [sp,#8].

囍孤女 2024-12-20 23:53:04
unsigned int fun
(
    unsigned int a,
    unsigned int b,
    unsigned int c,
    unsigned int d,
    unsigned int e,
    unsigned int f
)
{
    a+=1;
    a|=b+2;
    a&=c+4;
    a^=d+5;
    a-=e+6;
    a|=~f;
    return(a);
}


00000000 <fun>:
   0:   e2800001    add r0, r0, #1
   4:   e2811002    add r1, r1, #2
   8:   e181c000    orr ip, r1, r0
   c:   e2822004    add r2, r2, #4
  10:   e002100c    and r1, r2, ip
  14:   e59d0000    ldr r0, [sp]
  18:   e2833005    add r3, r3, #5
  1c:   e023c001    eor ip, r3, r1
  20:   e59d1004    ldr r1, [sp, #4]
  24:   e060200c    rsb r2, r0, ip
  28:   e2420006    sub r0, r2, #6
  2c:   e1e03001    mvn r3, r1
  30:   e1800003    orr r0, r0, r3
  34:   e12fff1e    bx  lr

前四个依次为 r0 = a、r1 = b、r2 = c、r3 - d,然后将其余的按相反顺序压入,使 sp+0 为 e,sp+4 为 f。

如果你说的是一个 64 位整数,那么它将需要两个寄存器,所以你可以用四个 int 或两个 int 和一个 long long 或两个 long long 等来使用 r0-r3。

unsigned int fun
(
    unsigned int a,
    unsigned int b,
    unsigned int c,
    unsigned int d,
    unsigned int e,
    unsigned int f
)
{
    a+=1;
    a|=b+2;
    a&=c+4;
    a^=d+5;
    a-=e+6;
    a|=~f;
    return(a);
}


00000000 <fun>:
   0:   e2800001    add r0, r0, #1
   4:   e2811002    add r1, r1, #2
   8:   e181c000    orr ip, r1, r0
   c:   e2822004    add r2, r2, #4
  10:   e002100c    and r1, r2, ip
  14:   e59d0000    ldr r0, [sp]
  18:   e2833005    add r3, r3, #5
  1c:   e023c001    eor ip, r3, r1
  20:   e59d1004    ldr r1, [sp, #4]
  24:   e060200c    rsb r2, r0, ip
  28:   e2420006    sub r0, r2, #6
  2c:   e1e03001    mvn r3, r1
  30:   e1800003    orr r0, r0, r3
  34:   e12fff1e    bx  lr

The first four are r0 = a, r1 = b, r2 = c, r3 - d, in order, and then the rest are pushed in reverse order so that sp+0 is e and sp+4 is f.

If you have say a 64 bit integer then that will take two registers, so you could use up r0-r3 with four ints or two ints and a long long, or two long longs, etc.

最终幸福 2024-12-20 23:53:04

我记得,尽可能多的可以通过寄存器传递(r0-r3或4个字)都是通过寄存器传递的。其余的通过堆栈传递。

i remember, as many as can be passed through registers(r0-r3 or 4 words) are passed via registers. and the rest are passed through the stack.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文