繁体   English   中英

从arm程序集调用c函数时如何传递long long-type参数?

[英]How to pass a long long-typed parameter when calling c function from arm assembly?

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

int foo(int a, long long b);

我试图从手臂组装中调用它,但我不知道如何处理第二个参数( long long )。

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

这两个要求都可以容纳strd / ldrd指令,这可以在一条指令中保存两个寄存器。

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

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

(注意:错误的答案;不能删除它,因为评论包含信息)

根据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)

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

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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM