2

I'm currently learning Assembly.

I wrote a function to print strings:

global sys_print
sys_print:
    ; store the stack pointer
    push    rbp
    mov     rbp, rsp

    ; get the string to print
    mov     rdi, [rbp + 0x18]

    ; get length of the string
    mov     rsi, [rbp + 0x10]

    ; print the string
    mov     rax, 0x2000004
    mov     rdx, rsi
    syscall

    ; restore the stack pointer
    pop     rbp
    ret

And then used this function in a second script:

extern sys_print
global _main

section .data
hello db 'Hello, world!', 0x0a, 0
len equ $ - hello

section .text
    align 16
_main:
    lea rdi, [rel hello]
    mov rsi, len
    push rdi
    push rsi
    call sys_print
    add rsp, 16

    mov eax, 0x2000001
    xor edi, edi
    syscall

I tryied many diffrent things but when I compile and run the assembly just nothing happens.

$ ./hello                           
$

I compile the file with the defintion of the print function using:

$ nasm -f macho64 sys_print.asm -o libraryObjects/sys_print.o

And the main.asm file I compile using:

$ nasm -f macho64 -o main.o main.asm
$ gcc -o hello main.o sys_print.o   

I don't understand why it doesn't work. The print_sys function must be in a diffrent file goal is to link it in.

Thanks for you help!

OS: macos ventura CPU: intel dual chip

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Fab boy
  • 41
  • 4
  • In the head of the sys_print function is `global sys_print` so i didn't forget that – Fab boy Apr 28 '23 at 08:46
  • 1
    Your `sys_print` function doesn't seem to set a file descriptor in EDI. Like `mov edi, 1` for stdout. `write(int fd, void *buf, size_t len)` also takes the pointer in RSI, that's why the length goes in RDX (the 3rd arg-passing slot). – Peter Cordes Apr 28 '23 at 10:07
  • Also, it's odd that you pass function args on the stack in 64-bit code. The standard calling convention (x86-64 System V) passes the first 6 args in registers. [What's the best way to remember the x86-64 System V arg register order?](https://stackoverflow.com/q/63891991) – Peter Cordes Apr 28 '23 at 10:08
  • MacOS has `dtruss` for tracing system calls (similar to Linux `strace`), so you can use it to see your program returning either `EBADF` or `EFAULT` from the `write` system call. – Peter Cordes Apr 28 '23 at 10:11
  • Near duplicates: [step by step hello world in assembly for mac OS](https://stackoverflow.com/q/69857083) / [How to get this simple assembly to run?](https://stackoverflow.com/q/34190930) / [How to correctly use the "write" syscall on MacOS to print to stdout?](https://stackoverflow.com/q/74913792) show the correct arg registers for a `write` system call. (And [How to trace system calls of a program in Mac OS X?](https://stackoverflow.com/q/31045575) for how you could have debugged this) – Peter Cordes Apr 28 '23 at 10:20

0 Answers0