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 prog开发者_如何学JAVAram 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)
精彩评论