【问题标题】:How to pass a long long-typed parameter when calling c function from arm assembly?从arm程序集中调用c函数时如何传递一个long long类型的参数?
【发布时间】:2013-03-14 15:04:40
【问题描述】:

我有一个 C 函数,看起来像:

int foo(int a, long long b);

我正在尝试从 arm 组件中调用它,但我不知道如何处理第二个参数(long long)。

【问题讨论】:

    标签: c assembly arm


    【解决方案1】:

    ARM EABI/AAPCS 指定 64 位类型应在 2 个彼此相邻的寄存器中传递,并且第一个寄存器必须为偶数。在小端模式下,高位部分位于编号较高的寄存器中,而低位部分位于编号较低的寄存器中。在大端模式下,反之亦然。

    这两个要求都是为了适应 strd/ldrd 指令,它可以在一条指令中保存两个寄存器。

    因此,要在小端模式下为您的示例传递 0x0123456789abcdef,您必须按以下方式加载寄存器:

    mov r0, a
    // R1 is unused
    ldr r2, =0x89abcdef
    ldr r3, =0x01234567
    

    【讨论】:

      【解决方案2】:

      (注意:错误答案;无法删除,因为 cmets 包含信息)

      根据 ARM ABI,第二个参数在寄存器r1r2 中传递。如果你的机器是 little-endian,请通过 r1 中的低部分和 r2 中的高部分(我不知道这是否与 big-endian 机器相反)。所以要调用带有参数的函数,例如0x123456789abcd:

      MOV r0, ... (the value of "a")
      MOV r1, #0x6789abcd
      MOV r2, #0x12345
      ... (call the function)
      

      【讨论】:

      • 我以前试过这个,但我得到了错误的值,witch 看起来像 r0 中的低部分,hi 部分在 r1,“a”也得到了 r0 的值
      • @ZhangGuang 这是有价值的信息;你应该编辑你的问题并描述你到底做了什么,你期望什么,你得到了什么。
      • 这是我的汇编函数: ; int test_asm_args ; void* ptrFunc test_asm_args: ;r0 = ptrFunc STMFD r13!, {r4-r11,r14} MOV r8, r0 ;r8 = ptrFunc LDR r0, =0x123 LDR r1, =0x6789abcd LDR r2, =0x12345 LDR r3, =0x321 BLX r8 ;call ptrFunc LDMFD r13!, {r4-r11,pc} 我从 c 调用了这个函数: int main() { return test_reg((void*)foo); } int foo(int a, long long b) { // 打印 a & b 的值 } 最后我得到 a = 0x123 b = 0x8a8500000321 (0x8a85 是 foo 的地址,0x321 是 r3)
      【解决方案3】:

      只要问编译器它会告诉你一切......

      int foo ( int a, long long b );
      
      int bar  ( void )
      {
          return(foo(0xAABB,0x1122334455667788LL));
      }
      

      我更喜欢编译然后反汇编而不是编译成asm,更容易阅读。

      arm-none-eabi-gcc -c -O2 fun.c -o fun.o
      arm-none-eabi-objdump -D fun.o
      
      fun.o:     file format elf32-littlearm
      
      
      Disassembly of section .text:
      
      00000000 <bar>:
         0:   e92d4008    push    {r3, lr}
         4:   e59f001c    ldr r0, [pc, #28]   ; 28 <bar+0x28>
         8:   e28f3010    add r3, pc, #16
         c:   e893000c    ldm r3, {r2, r3}
        10:   ebfffffe    bl  0 <foo>
        14:   e8bd4008    pop {r3, lr}
        18:   e12fff1e    bx  lr
        1c:   e1a00000    nop         ; (mov r0, r0)
        20:   55667788    strbpl  r7, [r6, #-1928]!   ; 0x788
        24:   11223344    teqne   r2, r4, asr #6
        28:   0000aabb            ; <UNDEFINED> instruction: 0x0000aabb
        2c:   e1a00000    nop         ; (mov r0, r0)
      

      答案是r0包含第一个参数,r1跳过,r2/r3包含long long。

      【讨论】:

        猜你喜欢
        • 2020-09-21
        • 2011-09-30
        • 1970-01-01
        • 2016-04-12
        • 2013-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多