2

For the life of me I can not figure out why this will not print to screen. Doesn't crash or seg fault, just exits. Yes I am new, and looking for a tutor as a matter of fact, if anyone could be so kind as to help out it would be grealty appreciated.

; Hello World in nasm
;

; Intel Linux bt 2.6.39.4 #1 SMP x86_64 GNU/Linux
; NASM version 2.07
; ld 2.20.1-system.20100303
;
; Compile to 32bit with debugging symbols:
; nasm -g -f elf32 -F dwarf string-w.asm
; ld -g -melf_i386 -o string-w string-w.o
; file string-w.asm

[section .data]
    msg db      "Hello World",0xa,0x0
    len equ     $ - msg

[section .bss]

[section .text]

   global _start

_start:

    push dword len
    push dword msg
    push dword 1    ; Stdout
    mov eax,0x4     ; write
    int 0x80
    ret
    add esp,12      

    push    dword 0
    mov     eax, 0x1     ; exit
    int     0x80

Again, any help is greatly appreciated and if anyone is looking for a student, I'm ready to volunteer.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
ayright
  • 21
  • 2

3 Answers3

1

You can still use int 0x80, your problem is your using it wrong. You don't push parameters onto the stack, instead, parameters are passed in registers. Theses links will show what calls use what registers: Linux System Call Table Linux System call Reference

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Gunner
  • 5,780
  • 2
  • 25
  • 40
1

What you've got there looks almost like BSD code - BSD pushes parameters on the stack and uses int 80h. Linux system calls take the parameters in registers, ebx, ecx, edx (that's all you need), esi, edi... possibly even ebp. You shouldn't need to ret or clean up the stack.

mov edx, len
mov ecx, msg
mov ebx, 1 ; file descriptor for stdout
mov eax, 4 ; sys_write call number (for 32-bit)
int 80h

mov ebx, 0 ; exit code
mov eax, 1 ; sys_exit call number
int 80h

To call write() from the C library (which some people claim is preferable)...

; nasm -f elf32 myprog.asm
; ld -o myprog myprog.o -I/lib/ld-linux.so.2 -lc -melf_i386
global _start
extern write

section .data
     msg db "Hello World", 10
     len equ $ - msg

section .text
_start:
    push len
    push msg
    push 1
    call write
    add esp, 4 * 3

    mov ebx, 0
    mov eax, 1
    int 80h

You'll have to link it a little differently. You've got the right idea... in fact you've got two right ideas, you've just got 'em mixed up! :)

Don't try to ret from the _start label - it isn't called, it's jumped to!

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Frank Kotler
  • 1,462
  • 1
  • 8
  • 4
  • Thank you everyone for your answers. You have given me a wealth of information and links to reading that have already proven quite useful. For example I didn't know registers had to be populated in a specific order. Narue has written a great introductory tutorial but it deals with all parameters being pushed to the stack and using things like _printf which only worked within cygwin and not on linux. On that note, thank you Narue for getting me interested and thanks to everyone that responded for getting me hooked. – ayright Oct 12 '12 at 12:53
0

Well, basically int 0x80 got deprecated, use SYSENTER instead.

Related thread with an example of exactly what you're trying to do... though written with a slightly different assembly syntax.

This was a long time ago http://articles.manugarg.com/systemcallinlinux2_6.html

Google around for sysenter ... or sysenter vs int 0x80.

Community
  • 1
  • 1
xception
  • 4,241
  • 1
  • 17
  • 27