0

I have written x32 hello world on osx.

section .data                                           ; .data section declaration
    hello_text      db      "Hello, World!",10          ; declared "Hello, World!\n" as bytes
    hello_length    equ     $ - hello_text              ; length of hello_bytes in hex

section .text                                           ; .text section declaration
    global _main

_main:
    push    dword hello_length                          ; push length of the string to stack
    push    dword hello_text                            ; push pointer to string to stack
    push    dword 1                                     ; push stdout (1) to stack
    mov     eax, 4                                      ; syscall - write
    sub     esp, 4                                      ; subtract 4 bytes from stack pointer (move)
    int     0x80                                        ; interrupt (call kernel)

    add     esp, 16                                     ; why we moving pointer?

    push    dword 0                                     ; set exit call param
    mov     eax, 1                                      ; syscall - exit
    sub     esp, 12                                     ; why?
    int     0x80                                        ; interrupt (call kernel)

Can anyone please explain why we have to push arguments to stack and what exactly we are doing with stack pointer in above program?

Initially I did this, but it didn't work.

   mov eax, 4
   mov ebx, 1
   mov ecx, userMsg
   mov edx, lenUserMsg
   int 80h

Is it osx or bsd conventions?

Another question is regarding x64 hello world.

_main:
    mov     rax, 0x2000004                              ; syscall - write
    mov     rdi, 1                                      ; write stdout
    mov     rsi, hello_text                             ; string pointer to stack pointer
    mov     rdx, hello_length                           ; string length to data register
    syscall                                             ; call kernel

    mov     rax, 0x2000001                              ; syscal - exit
    mov     rdi, 0                                      ; exit argument (return 0)
    syscall                                             ; call kernel

Why we using registers rsi / rsi instead of ebx / ecx?

If that's mac / bsd specific, can anyone point me to documentation pls.

Jbwz
  • 185
  • 15
  • 4
    Unrelated to your question: note that 32 bit support has been discontinued in macOS. 32 bit binaries will cease working in the near future and toolchain support has already been droppped. Consider learning 64 bit assembly instead. – fuz Jul 29 '20 at 17:15
  • Any chance that `eax` to 1 / `int 0x80` needs 16 bytes of stack space for its call? – Michael Dorgan Jul 29 '20 at 17:17
  • @fuz thats actually very useful info, thank you very much – Jbwz Jul 29 '20 at 17:19
  • 3
    @MichaelDorgan: that's FreeBSD / MacOS's 32-bit system-call calling convention: args on the stack above ESP (with a gap for a return address for a libc system-call wrapper function), totally different from the 32-bit Linux convention, and different from the x86-64 convention. – Peter Cordes Jul 29 '20 at 17:25

0 Answers0