Author Topic: Simple code which goes into seg fault  (Read 10513 times)

Offline neurophobos

  • Jr. Member
  • *
  • Posts: 11
  • Country: 00
  • Spengler: "We'll cross the streams"
Simple code which goes into seg fault
« on: May 18, 2014, 09:40:51 PM »
Hi everyone.
As the title says, I've a piece of code, I don't know what's its use, so I compiled and linked, everything goes fine, until I run it, and i get segmentation fault from loader.
I cannot understand why, I used gdb to see what's goin' on, no hints. I thought it was an issue with the usage of registers, so i pushed, popped, tried different combinations, but none of them worked. I post this code, could you help me to understand?
Thank you all!
N.

Code: [Select]
section .text

push ebx

xor ebx, ebx
mov ebx, 4
write_hex:
mov byte bh, bl
shr byte bl, 4
add byte bl, 0x30
cmp byte bl, 0x3a
jb short .number_1
add byte bl, 0x07

.number_1:
mov byte [hex_number], bl
and byte bh, 0x0f
add byte bh, 0x30
cmp byte bh, 0x3a
jb short .number_2
add byte bh, 0x07

.number_2:
mov byte [hex_number + 1], bh
mov dword eax, 4
mov dword ebx, 1
mov dword ecx, hex_text
mov dword edx, 9
int byte 0x80

pop ebx

ret

section .data

hex_text: db "ebx: "
hex_number: db "00h", 10

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Simple code which goes into seg fault
« Reply #1 on: May 18, 2014, 10:48:09 PM »
Just what did you do with this, neurophobos? Ending in "ret" as it does, it is apparently intended to be called from something. Lacking a caller, I tried assembling and linking it "freestanding". As expected, ld warns about not finding an entrypoint, and guesses at one. This entrypoint is not called ("argc" is the very first thing on the stack), so ending in "ret" segfaults, as expected. Before doing so, it prints the expected text, so it "kinda works".

To get rid of the segfault, either replace the "ret" with an exit:
Code: [Select]
; ret
mov eax, 1
mov ebx, 0
int 80h
... or call it from something, and do something sensible (like exit) after it returns. This caller could be part of the same file, or could be a separate module. If the latter, you'll want to declare your function "global" (in this file) and "extern" in the calling file. (C may assume this, if you're calling it from C)

To keep it simple...
Code: [Select]
; nasm -f elf32 myfile.asm
; ld -o myfile myfile.o -m elf_i386

global _start ; tell ld about this so it won't have to guess

section .text
_start:
        nop ; may help gdb


        call myfunc
exit:
        mov eax, 1 ; sys_exit
        xor ebx, ebx ; claim no error
        int 80h
; -------------------

;---------------------
myfunc:
push ebx

xor ebx, ebx
mov ebx, 4
write_hex:
mov byte bh, bl
shr byte bl, 4
add byte bl, 0x30
cmp byte bl, 0x3a
jb short .number_1
add byte bl, 0x07

.number_1:
mov byte [hex_number], bl
and byte bh, 0x0f
add byte bh, 0x30
cmp byte bh, 0x3a
jb short .number_2
add byte bh, 0x07

.number_2:
mov byte [hex_number + 1], bh
mov dword eax, 4
mov dword ebx, 1
mov dword ecx, hex_text
mov dword edx, 9
int byte 0x80

pop ebx

ret

section .data

hex_text: db "ebx: "
hex_number: db "00h", 10

If you tell us more about how you want to use this, we may be able to help more...

Best,
Frank

Offline neurophobos

  • Jr. Member
  • *
  • Posts: 11
  • Country: 00
  • Spengler: "We'll cross the streams"
Re: Simple code which goes into seg fault
« Reply #2 on: May 19, 2014, 06:30:58 AM »
Such a stupid error...I isolated this piece of code from a bigger one, I wanted to understand what it did...
As you say, in the bigger one this is a function called from somewhere, but here isolated as it is, that ret is the problem.
Got it
Thank you very much Frank!