【问题标题】:Arm Assembly - Calling function with more than 4 argumentsArm Assembly - 使用超过 4 个参数调用函数
【发布时间】:2011-12-23 03:20:00
【问题描述】:

我知道在程序集中调用函数时,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 个字节。额外的 3 个参数是 48 字节还是全部?

【问题讨论】:

    标签: assembly stack arm disassembly


    【解决方案1】:

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

    【讨论】:

    • 那么剩下的参数是从堆栈指针的开头开始的吗?
    • 对,这就是[sp]的意思。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:
      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 位整数,那么它将占用两个寄存器,所以你可以用 r0-r3 用四个整数或两个整数和一个 long long 或两个 long long 等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-15
        • 1970-01-01
        • 2012-01-04
        • 1970-01-01
        • 2019-05-23
        • 2020-01-26
        • 1970-01-01
        相关资源
        最近更新 更多