Linux中的NASM代码给我分段错误

时间:2011-02-12 20:29:50

标签: linux ubuntu segmentation-fault nasm

我开始学习如何使用NASM汇编编程语言编写程序。我写了这个简单的程序,提示用户输入两个数字,然后将两个操作数加在一起。我把它编译成没有错误或警告,但是当它提示用户输入两个数字并且它开始添加两个数字时它会打印出分段错误并且程序结束。我知道分段错误相当于Win32世界中的访问读/写违规异常。但是,因为我不知道如何调试NASM代码;我无法弄清楚出了什么问题。我怀疑它与无效指针有关;但我不知道。以下是代码:

section .data 
    msg1: db 'Please Enter A Number: ', 0
    length1: equ $ - msg1
    msg2: db 'Please Enter A Second Number: ', 0
    length2: equ $ - msg2

section .bss
    operand1: resb 255
    operand2: resb 255
    answer: resb 255
section .text
    global _start

_start:

    ; Print first message

    mov eax, 4
    mov ebx, 1
    mov ecx, msg1
    mov edx, length1
    int 80h

    ; Now read value

    mov eax, 3
    mov ebx, 1
    mov ecx, operand1
    mov edx, 255
    int 80h

    ; Print second message

    mov eax, 4
    mov ebx, 1
    mov ecx, msg2
    mov edx, length2
    int 80h

    ; Now read second value

    mov eax, 3
    mov ebx, 1
    mov ecx, operand2
    mov edx, 255
    int 80h

    ; Now add operand1 and operand2 and print answer

    mov eax, 4
    mov ebx, 1
    xor ecx, ecx ; Make the ecx register 0
    mov ecx, operand1
    add ecx, operand2
    mov edx, 510
    int 80h

2 个答案:

答案 0 :(得分:0)

(旁白:你应该从STDIN_FILENO = 0开始,而不是STDOUT_FILENO = 1。此外,你正在写一个NUL字符,你不应该。)

问题是operand1operand2是包含您已阅读过的字符的内存位置的地址。添加它们时,会得到指向无效内存的指针。

你必须先将它们转换为整数,添加它们,然后转换回字符串,然后才能写出来。

答案 1 :(得分:0)

ecx中的值是在调用int 80h时要打印的字符串的地址。最后一部分没有意义

mov eax, 4
mov ebx, 1
xor ecx, ecx ; Make the ecx register 0
mov ecx, operand1
add ecx, operand2 ; **<<< invalid memory address now in ECX !!!**
mov edx, 510
int 80h

因为你正在添加字符串operand1的地址和字符串operand2的地址,并试图打印任何位于ant的结果地址,这很可能无处可寻。

要使用gdb调试程序,您可以这样做:

  

nasm -f elf64 -g -l q1.lst q1.asm   gcc -o q1 q1.o

我将“_start”替换为“main”,以便gcc不会抱怨,如果你在32位平台上构建,你可以跳过“-f elf64”中的64位。

  

gdb q1

以下是f gdb会话的示例:

(gdb)br main 断点1在0x4004d0:文件q1.asm,第20行。 (gdb)r 启动程序:/ home / anonymous / Projects / asm / q1

Breakpoint 1, main () at q1.asm:20
20      mov eax, 4
(gdb) n
21      mov ebx, 1
(gdb) n
22      mov ecx, msg1
(gdb) n
23      mov edx, length1
(gdb) p msg1
$1 = 1634036816
(gdb)