我有一个C函数女巫看起来像:
int foo(int a, long long b);
我正试图从手臂装配中调用它,但我不知道如何处理第二个参数(long long
)。
答案 0 :(得分:3)
ARM EABI/AAPCS指定64位类型应该在2个寄存器中传递,这些寄存器彼此相邻,并且第一个寄存器必须是偶数。在小端模式中,高部分位于较高编号的寄存器中,而低部分位于较低编号的寄存器中。在大端模式中,反之亦然。
这两个要求都可以容纳strd / ldrd指令,这可以在一条指令中保存两个寄存器。
因此,要在小端模式下为您的示例传递0x0123456789abcdef,您必须按以下方式加载寄存器:
mov r0, a
// R1 is unused
ldr r2, =0x89abcdef
ldr r3, =0x01234567
答案 1 :(得分:0)
(注意:错误的答案;因为评论包含信息而无法删除)
根据ARM ABI,第二个参数在寄存器r1
和r2
中传递。如果你的机器是little-endian,请传递r1
中的低部分和r2
中的高部分(我不知道对于big-endian机器是否相反)。所以用一个参数调用函数,例如0x123456789abcd:
MOV r0, ... (the value of "a")
MOV r1, #0x6789abcd
MOV r2, #0x12345
... (call the function)
答案 2 :(得分:0)
只要问编译器就会告诉你一切......
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。