简体   繁体   English

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

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

I have a C function witch looks like: 我有一个C函数女巫看起来像:

int foo(int a, long long b);

I'm trying to call it from arm assembly, but I don't know how to deal with the second parameter( long long ). 我试图从手臂组装中调用它,但我不知道如何处理第二个参数( long long )。

The ARM EABI/AAPCS specifies that 64bit types should be passed in 2 registers which are next to each other and the first register must be even numbered. ARM EABI / AAPCS指定64位类型应该在2个寄存器中传递,这些寄存器彼此相邻,并且第一个寄存器必须是偶数。 In little endian mode the high part resides in the higher numbered register, while the low part is put in the lowered numbered one. 在小端模式中,高部分位于较高编号的寄存器中,而低部分位于较低编号的寄存器中。 In big endian mode it's vice versa. 在大端模式中,反之亦然。

Both requirements are there to accomodate the strd/ldrd instructions, which can save two registers in a single instructions. 这两个要求都可以容纳strd / ldrd指令,这可以在一条指令中保存两个寄存器。

So, to pass 0x0123456789abcdef for your example in little endian mode you have to load the registers in the following way: 因此,要在小端模式下为您的示例传递0x0123456789abcdef,您必须按以下方式加载寄存器:

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

(Beware: wrong answer; cannot delete it because the comments contain info) (注意:错误的答案;不能删除它,因为评论包含信息)

According to the ARM ABI, the second parameter is passed in registers r1 and r2 . 根据ARM ABI,第二个参数在寄存器r1r2传递。 If your machine is little-endian, pass the low part in r1 and the high one in r2 (i don't know if this is opposite for big-endian machines). 如果您的机器是little-endian,则通过r1的低位部分和r2的高位(我不知道这对于big-endian机器是否相反)。 So to call the function with a parameter eg 0x123456789abcd: 所以用一个参数调用函数,例如0x123456789abcd:

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

Just ask the compiler it will tell you everything... 只要问编译器就会告诉你一切......

int foo ( int a, long long b );

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

I prefer to compile then disassemble rather than compile to asm, easier to read. 我更喜欢编译然后反汇编而不是编译为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)

and the answer is r0 contains the first parameter, r1 skipped and r2/r3 contain the long long. 答案是r0包含第一个参数,r1跳过,r2 / r3包含long long。

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

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