简体   繁体   中英

NASM Code In Linux Gives Me Segmentation Fault

I started learning how to write programs using the NASM assembly programming language. I wrote this simple program that prompts the user to enter two numbers and then adds the two operands together. I got it to compile with no errors or warnings, but when it prompts the user for the two numbers and it begins to add the two numbers it prints out segmentation fault and program ends. I know a segmentation fault is the equivalent to an access reading / writing violation exception in the Win32 world. But, because I don't know how to debug NASM code; I can't figure out what is wrong. I suspect it has to do with an invalid pointer; but I don't know. Here is the code below:

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

(Aside: you should be reading from STDIN_FILENO = 0 , not STDOUT_FILENO = 1 . Also, you're writing a NUL character and you shouldn't.)

The problem is that operand1 and operand2 are addresses to memory locations holding characters you've read. When you add them, you get a pointer to invalid memory.

You'll have to convert them to integers, add them, and convert back to a string, before you can write it out.

Value in ecx is an address of string that is to be printed when you call int 80h. Last part does not make sense

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

because you are adding address of string operand1 and address of string operand2 and trying to print whatever is located ant resulting address which is most likely points to nowhere.

To debug your program with gdb you can do:

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

I replaced the "_start" with "main" so that gcc won't complain, and you can skip the 64 in "-f elf64" if you are building on 32 bit platform.

gdb q1

Here is an example f gdb session:

(gdb) br main Breakpoint 1 at 0x4004d0: file q1.asm, line 20. (gdb) r Starting program: /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) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM