0

以下は、本のプログラム (Introduction to 64 Bit Intel Assembly Language Programming for Linux, by Seyfarth, 2012) の第 9 章です。障害 (gdb 内) は次のとおりです。

プログラム受信信号 SIGSEGV、セグメンテーション違反。0x00007ffff7aa10a5 in __printf_size (fp=0x400400, info=0x0, args=) at printf_size.c:199 199 printf_size.c: そのようなファイルまたはディレクトリはありません。

この章までは、以下を使用して「オブジェクト ファイルを作成する」ことに成功しました。

yasm -f elf64 -g dwarf2 -l exit.lst exit.asm

その後、

ld -o prgm prgm.o

これは本からコピーしたプログラムです (l 10 push rbp; 最初に rem'd しましたが、結果は同じでした):

    segment .text
    global  main
    extern  printf

;   void print_max  ( long a, long b )
;   {
a   equ 0
b   equ 8
print_max:
    push    rbp;     ;normal stack frame
    mov     rbp, rsp
;   leave space for a, b and max
    sub     rsp, 32
;   int max;
    max equ 16
    mov [rsp+a], rdi ; save a
    mov [rsp+b], rsi ; save b
;   max = a;
    mov [rsp+max], rdi
;   if ( b > max ) max = b;
    cmp rsi, rdi
    jng skip
    mov [rsp+max], rsi
skip:
    ;   printf ( "max(%1d,%1d ) = %1d\n",
    ;                a, b, max );
    segment .data
fmt db  'max(%1d,%1d) = %1d',0xa,0
    segment .text
    lea rdi, [fmt]
    mov rsi, [rsp+a]
    mov rdx, [rsp+b]
    mov rcx, [rsp+max]
    call printf
 ; }
    leave
    ret

main:
    push    rbp
    mov     rbp, rsp
;   print_max ( 100, 200 );
    mov     rdi, 100    ;first parameter
    mov     rsi, 200    ;second parameter
    call    print_max
    xor     eax, eax    ;to return 0
    leave
    ret

この章の前のプログラム (「Hello World」の例) で同様のセグメンテーション違反が発生した後、

gcc -o prgm prgm.o

このプログラムまで機能していました。

4

2 に答える 2

1

C ライブラリの関数を使用する場合は、gcc を使用してリンクするのが最も簡単な方法です。これは、gcc が「舞台裏」でいくつかの処理を行うためです。

just を使用するにldは、ld-linux-x86-64.so.2 に対してリンクし、それを渡して-lcC ライブラリにリンクする必要があります。

次に、使い方がprintf間違っています。浮動小数点レジスタを使用していない場合 (使用していない場合)、「ゼロ アウト」する必要がありますrax

また、C ライブラリに対してリンクしているため、 からだけretではなく、 をmain呼び出しますexit

lea     rdi, [fmt]
mov     rsi, [rsp+a]
mov     rdx, [rsp+b]
mov     rcx, [rsp+max]
xor     rax, rax                      ; # of floating point registers used.
call    printf

と:

;   print_max ( 100, 200 );
mov     rdi, 100    ;first parameter
mov     rsi, 200    ;second parameter
call    print_max
xor     eax, eax    ;to return 0
leave

xor     rdi, rdi
call    exit

ld -o $(APP) $(APP).o -lc -I/lib64/ld-linux-x86-64.so.2

そして出力:

最大 (100,200) = 200

于 2014-01-25T01:42:39.457 に答える