4

私はC関数の魔女が次のように見えます:

int foo(int a, long long b);

アームアセンブリから呼び出そうとしていますが、2番目のパラメータ(long long)の処理方法がわかりません。

4

3 に答える 3

3

ARM EABI / AAPCSは、64ビットタイプを互いに隣接する2つのレジスタで渡す必要があり、最初のレジスタには偶数番号を付ける必要があることを指定しています。リトルエンディアンモードでは、高い部分は高い番号のレジスタにあり、低い部分は低い番号のレジスタにあります。ビッグエンディアンモードでは、その逆です。

両方の要件は、strd / ldrd命令に対応するためのものであり、1つの命令で2つのレジスタを保存できます。

したがって、リトルエンディアンモードで例の0x0123456789abcdefを渡すには、次の方法でレジスタをロードする必要があります。

mov r0, a
// R1 is unused
ldr r2, =0x89abcdef
ldr r3, =0x01234567
于 2013-03-25T08:15:57.213 に答える
0

(注意:間違った答え。コメントに情報が含まれているため、削除できません)

ARM ABIによると、2番目のパラメータはレジスタr1とで渡されますr2。マシンがリトルエンディアンの場合は、低い部分r1と高い部分を渡しますr2(これがビッグエンディアンのマシンの場合と反対かどうかはわかりません)。したがって、0x123456789abcdなどのパラメーターを使用して関数を呼び出すには、次のようにします。

MOV r0, ... (the value of "a")
MOV r1, #0x6789abcd
MOV r2, #0x12345
... (call the function)
于 2013-03-25T07:41:09.080 に答える
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にはlonglongが含まれるというものです。

于 2013-03-25T14:02:38.450 に答える