4

私はいくつかの Linux アセンブリ マニュアルを読んでいて、printf() 関数の使用に関するアイデアを見つけました。デバッグの理由でレジスタ値をバイナリ形式で端末に出力する必要がありますが、今は単にその機能をテキストでテストしようとしています。

pushl の代わりに pushq を使用している場合、segfault が原因でスタックします。このプログラムを変更して、文字列とバイナリ形式のレジスタを出力するにはどうすればよいですか?

.data
input_prompt:
    .string "Hello, world!"

printf_format:
    .string "%5d "

printf_newline:
    .string "\n"

size:
    .long 0

.text
.globl main
main:
    pushq $input_prompt
    call  printf

    movl  $0, %eax
    ret

GCC によって次のようにコンパイルされました。

gcc tmp.S -o tmp
4

1 に答える 1

10

Linux (および Windows)のx86-64 呼び出し規約では、最初のいくつかの引数はスタックではなくレジスタにあります

http://www.x86-64.org/documentation/abi.pdf (20 ページ)を参照してください。

具体的には:

  1. クラスが MEMORY の場合、引数をスタックに渡します。
  2. クラスが INTEGER の場合、シーケンス %rdi、%rsi、%rdx、%rcx、%r8、および %r9 の次に使用可能なレジスタが使用されます。
  3. クラスが SSE の場合、次に使用可能なベクトル レジスタが使用され、レジスタは %xmm0 から %xmm7 の順序で取得されます。
  4. クラスが SSEUP の場合、8 バイトは、最後に使用されたベクトル レジスタの次に使用可能な 8 バイト チャンクに渡されます。
  5. クラスが X87、X87UP、または COMPLEX_X87 の場合、メモリに渡されます。

クラスは、INTEGER汎用レジスタに収まるものであれば何でもよいため、文字列ポインタにも使用できます。

于 2012-06-01T21:03:58.063 に答える