Comment passer un paramètre long long lors de l’appel de la fonction c depuis un assemblage de arm?

J’ai une fonction C qui ressemble à:

int foo(int a, long long b); 

J’essaie d’appeler cela de l’assemblage du arm, mais je ne sais pas comment traiter le deuxième paramètre ( long long ).

L’ ARM EABI / AAPCS spécifie que les types 64 bits doivent être passés dans 2 registres adjacents et que le premier registre doit être numéroté de manière paire. En mode little endian, la partie haute se trouve dans le registre au numéro le plus élevé, tandis que la partie basse est placée dans le registre au numéro inférieur. En mode Big Endian, c’est l’inverse.

Les deux exigences sont là pour accueillir les instructions strd / ldrd, qui permettent de sauvegarder deux registres dans une seule instruction.

Ainsi, pour passer 0x0123456789abcdef à votre exemple en mode little endian, vous devez charger les registres de la manière suivante:

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

(Attention: mauvaise réponse; impossible de la supprimer car les commentaires contiennent des informations)

Selon l’ABI ARM, le deuxième paramètre est transmis aux registres r1 et r2 . Si votre machine est little-endian, passez la partie basse en r1 et la partie haute en r2 (je ne sais pas si c’est le contraire pour les machines big-endian). Donc, pour appeler la fonction avec un paramètre, par exemple 0x123456789abcd:

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

Il suffit de demander au compilateur, il vous dira tout …

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

Je préfère comstackr puis désassembler plutôt que comstackr en asm, plus facile à lire.

 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 : 0: e92d4008 push {r3, lr} 4: e59f001c ldr r0, [pc, #28] ; 28  8: e28f3010 add r3, pc, #16 c: e893000c ldm r3, {r2, r3} 10: ebfffffe bl 0  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 ;  instruction: 0x0000aabb 2c: e1a00000 nop ; (mov r0, r0) 

et la réponse est r0 contient le premier paramètre, r1 ignoré et r2 / r3 contient long long.