2

アセンブリ言語で簡単なプログラムを作成し、64ビットのUbuntuOSで実行しようとしました。ただし、「セグメンテーション違反(コアダンプ)エラー」で失敗しました。

これが私のコードです:

    .section .data
    values :
        .int 10, 15, 20, 25, 30 ,35, 40, 45, 50, 55, 60
    output :
        .asciz "The value is %d\n"
   .section .text
   .globl main
   main :
        nop
        movl $0, %edi
   loop :
        movl values( , %edi, 4), %eax
        pushq %rax
        pushq $output
        call printf
        addl $8, %esp
        inc %edi
        cmpl $11, %edi
        jne loop
        movl $0, %ebx
        movl $1, %eax
        int $0x80
4

1 に答える 1

3

コードには複数の問題があります。

From64bit Ubuntupushq %rax私はあなたが64ビットの実行可能ファイルを作ろうとしていると推測します。

その場合は、...

ここ:

pushq %rax
pushq $output
call printf
addl $8, %esp

関数呼び出し後にスタックのバランスが適切に取れていません。これが64ビットコードであることを今でも覚えていますか?に追加する必要があります。rspではなく、に追加する必要がありespます。また、2つの8バイトパラメータをプッシュする場合は、正確に2つの8バイトパラメータを削除する必要があります。つまり、8ではなく16を追加する必要があります。

しかし、それよりもさらに悪いです。64ビットモードでは、パラメータの受け渡しが異なります。rdi最初のパラメータは、レジスタ、、、、、およびにrsiあります。だから、それは私たちに与えます:rdxrcxr8r9

movq %rax, %rsi
movq $output, %rdi
movq $0, %rax ; number of vector registers used for var-arg-function printf()
call printf

ここ:

inc %edi

rdi呼び出しによって、およびこのレジスタをパラメータの受け渡しに使用することにより、の値を破棄しました。rdi呼び出しの前に手動でプッシュしてから、ポップバックする必要があります。または、グローバル変数に保存することもできます。プッシュアンドポップを選択する場合は、命令rspの前にスタックポインタが常に16バイト整列されていることを確認してください。call

ここ:

movl $0, %ebx
movl $1, %eax
int $0x80

32ビットのシステムコールインターフェイスを使用しています。64ビットプログラムでは、64ビットシステムコールインターフェイスを使用する必要があります。

movq $60, %rax ; sys_exit
movq $0, rdi ; return 0 (success)
syscall

さて、これにも問題があると思います。

movl $0, %edi
loop :
movl values( , %edi, 4), %eax

一般に、64ビットコードのアドレス計算では、32ビットレジスタと32ビット命令を使用しないでください。私はそれを次のように変更します:

movl $0, %rdi
loop :
movl values( , %rdi, 4), %eax

のアドレスがvalues2GB以上離れているために、2つのどちらも機能しない場合rip(事実:変位は、64ビットモードのほとんどの命令でメモリオペランドの32ビット符号付き整数に制限され、ほとんどの命令には変位のみのメモリオペランドがありません64ビットモードでエンコードする場合は、rip-relative addressingを使用します)、64ビットアドレスvaluesとインデックスを手動で追加し、4を掛けた配列にインデックスを追加する必要があります。切り捨てなしで64ビット追加を行うようにしてください。途中で。

必読:

  • SystemVアプリケーションバイナリインターフェイスAMD64アーキテクチャプロセッサ補足ドラフトバージョン0.99.6

  • さまざまなC++コンパイラおよびオペレーティングシステムの呼び出し規約ByAgnerFog

于 2012-07-14T05:03:18.770 に答える