【问题标题】:NASM Segmentation Fault ( strchrnul )NASM 分段错误 (strchrnul)
【发布时间】:2014-01-31 10:57:24
【问题描述】:

在 nasm 代码方面需要帮助。必须找到 intgr1 mod intgr2==0,但不能使用 DIV。 我遇到了分段错误。从 gdb 我发现:

程序收到信号SIGSEGV,分段错误。

0x00007ffff7aacd2a in strchrnul() from /lib/x86_64-linux-gnu/libc.so.6

我的程序:

;nasm -f elf64 main.nasm
;gcc -o main main.o -lc


section .text
    global main
    extern scanf 
    extern printf

section .data
    request1: db "Dividendo: ", 0
    request2: db "Divisor: ", 0
    message1: db "Eh divisivel", 0
    message2: db "Nao eh divisivel", 0
    formatin: db "%d", 0
    intgr1: times 4 db 0 ; 32-bits integer = 4 bytes
    intgr2: times 4 db 0 ;

main:
    push request1   ;imprime pedido dividendo
    call printf
    add esp, 4

    push intgr1 ;scanf do dividendo
    push formatin
    call scanf
    add esp, 8

    push request2   ;imprime pedido divisor
    call printf
    add esp, 4

    push intgr2 ;scanf do divisor
    push formatin
    call scanf
    add esp, 8

    mov eax, [intgr1]   
    mov ebx, [intgr2]
    jmp L1

L1: cmp eax, ebx    ;compara dividendo divisor
    jb L2       ;se < entao vai pra l2
    sub eax,ebx ;dividendo:=dividendo-divisor
    jmp L1      ;vai pra L1

L2: cmp eax, 0  ;compara dividendo e 0
    je L3       ;se igual vai para l3
    jmp L4      ;se nao vai para l4

L3: push message1   ;imprime que eh divisivel
    call printf
    add esp, 4

L4:push message2    ;imprime que nao eh
    call printf
    add esp, 4

    MOV AL, 1   ;termina o programa
    MOV EBX, 0 
    INT 80h

有人知道出了什么问题吗?

谢谢。

【问题讨论】:

    标签: gdb segmentation-fault nasm


    【解决方案1】:

    nasm -f elf64 main.nasm

    您正在组装 64 位应用程序?我们在 64 位域中不推送参数,而是传入寄存器。

    Calling conventions 查看表中x86-64 的行,它将告诉您Linux 在其调用约定中使用哪些寄存器。 RDI, RSI, RDX, RCX, R8, R9, XMM0–7

    您的printf 应该是:

    mov     rdi, request1
    xor     rax, rax
    call    printf
    

    你的printf调用需要一个格式参数,不然以后有问题,现在学习正确的方法,以后问题少了。

    同样,scanf 也是一样的:

    mov     rsi, intgr2
    mov     rdi, formatin
    xor     rax, rax
    call    scanf
    

    由于您与 C 库链接,您需要调用 exit 以便库可以进行清理。

    xor     rdi, rdi
    call    exit
    

    【讨论】:

    • 可以从 main 返回而不是调用 exit。
    猜你喜欢
    • 1970-01-01
    • 2016-09-10
    • 2013-07-24
    • 2015-01-09
    • 2012-06-26
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多