'I am getting segmentation fault - assembly
I'm trying assembly x86 but I got the zsh: segmentation fault ./test error.
I am trying to make some basic library myself to use later on. It's divided into three files - string.asm for string manipulation, stdio.asm for standard io operations, and libtest.asm for library testing. I was planning to add more functions, but I wanted to test these first.
;;;;;;;;;;;;;;;;;
;;; stdio.asm ;;;
;;;;;;;;;;;;;;;;;
global print ; void print(string* text)
extern strlen ; int32 strlen(string* string)
section .data
stdin dd 0
stdout dd 1
stderr dd 2
newline db 0x0a, 0x00
section .text
print:
push ebp
mov ebp, esp
push eax
push ebx
push ecx
push edx
; get parameters
mov ecx, dword [ebp+8]
; call strlen
push ecx
call strlen
add esp, 4
; moving length
mov ecx, eax
; moving syscall num and out desc
mov eax, 4
mov ebx, [stdout]
; syscall
int 0x80
pop edx
pop ecx
pop ebx
pop eax
mov esp, ebp
pop ebp
ret
;;;;;;;;;;;;;;;;;
;; string.asm ;;;
;;;;;;;;;;;;;;;;;
global strlen ; int32 strlen(string* str)
section .text
strlen:
push ebp
mov ebp, esp
push ebx
mov ebx, dword [ebp+8]
mov eax, 0
loop1:
cmp [ebx+eax], byte 0x00
inc eax
jne loop1
dec eax
pop ebx
mov esp, ebp
pop ebp
ret
;;;;;;;;;;;;;;;;;
;; libtest.asm ;;
;;;;;;;;;;;;;;;;;
global _start
extern print
section .data
msg db 'Hello, world!', 0x0a, 0x00
section .text
_start:
push msg
call print
add esp, 4
mov eax, 1
mov ebx, 0
int 0x80
Execution:
$ nasm -f elf32 stdio.asm
$ nasm -f elf32 string.asm
$ nasm -f elf32 libtest.asm
$ ld -m elf_i386 -o test stdio.o string.o libtest.o
$ ./test
I don't know where the error could be, so I would appreciate any help from you guys.
Thanks!
Solution 1:[1]
Two bugs:
; moving length
mov ecx, eax
; moving syscall num and out desc
mov eax, 4
mov ebx, [stdout]
; syscall
int 0x80
Referring to Linux system call conventions, the write system call needs the buffer pointer in ecx and the length in edx. You have the length in ecx and the buffer pointer is nowhere at all. Make it:
mov edx, eax
mov ecx, dword [ebp+8]
mov eax, 4
mov ebx, [stdout]
int 0x80
Next, look at:
cmp [ebx+eax], byte 0x00
inc eax
jne loop1
The inc instruction sets the zero flag according to its output. So your jne doesn't branch on the result of the cmp, but rather on whether eax was incremented to zero (i.e. wrapped around). So your loop will iterate far too many times.
The jne needs to be immediately after the cmp, with no other flag-modifying instructions in between. There are several ways you could rewrite. One would be:
mov eax, -1
loop1:
inc eax
cmp byte [ebx+eax], 0x00
jne loop1
Note this eliminates the need for the extra dec eax at the end.
After fixing these, the program works for me.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nate Eldredge |
