-3
section .data:
msg: db "Hello !"
msglen: equ $-msg

section .text:
      global _start:

_start:
      mov ebx,msg
      mov ecx,msglen
      mov eax,4
      int 80h
      mov eax,1
      int 80h

The code above doesn't work. But code below is working good.

section .data:
    msg: db "Hello !"
    msglen: equ $-msg

    section .text:
          global _start:

    _start:
          mov ecx,msg
          mov edx,msglen
          mov eax,4
          int 80h
          mov eax,1
          int 80h

All of i did was change ebx to ecx and ecx to edx. What is happen here ?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 2
    What errors do you get (if any) with the non-working code? How do you build? How do you run (if you can build)? Just what do you mean by "doesn't work"? Please take some time to refresh [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Aug 06 '19 at 10:51
  • 6
    You can't just randomly use registers. The system calls expect particular arguments in specific registers. See a [system call table](http://shell-storm.org/shellcode/files/syscalls.html). For sys_write `ebx` has to contain the file descriptor, `ecx` the buffer and `edx` the length. PS: I doubt you used `masm` that's more likely `nasm`. – Jester Aug 06 '19 at 10:56
  • nasm -f elf mycode.asm --> ld -m elf_i386 -s -o mycode mycode.o i haven't getting error,builting stage seems ok,but output is nothing when i use ebx register – ShooterLens Aim Aug 06 '19 at 10:58
  • 3
    _" i haven't getting error,builting stage seems ok"_ The assembler and linker has no knowledge about the semantics of a system call. That's an operating system thing. You need to follow the calling convention specified by the OS. – Michael Aug 06 '19 at 11:03
  • @Jester Oh,thank you.i didn't know these informations.İs there any book that you're recomment for noobs like me ? – ShooterLens Aim Aug 06 '19 at 11:05
  • I'm surprised this works at all. `section .text:` uses a custom section name that includes a colon, not the usual `.text`. That usually breaks from a non-executable segment. – Peter Cordes Apr 02 '20 at 17:35

1 Answers1

3

Your 2nd code works because write(0, "string", len) happens to work. FD 0 is stdin, but in a terminal programs are normally run with all 3 standard FDs referring to the same file description that's opened read/write on the TTY.

So you can write to stdin unless you redirect it to a file.

The kernel zeroes all the regs before entering user-space at your _start entry-point, so EBX = 0 if you don't set it. write(2) takes the file descriptor as its first arg.

Use strace ./a.out to see your system calls.


Your first code doesn't work because write("string", len, 0) passes a pointer as the file-descriptor number so sys_write will return -EBADF (or -EFAULT if it checks if len is a valid pointer first). The only valid fds will be 0, 1, or 2 unless you use a redirect like ./a.out 12345>&1 to open fd 12345 as a duplicate of 1. Again, use strace.

And read the docs about system-call calling conventions. What are the calling conventions for UNIX & Linux system calls on i386 and x86-64 has links.

See also https://stackoverflow.com/tags/x86/info for links to more docs/manuals and guides.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847