0

In x86-32 you push arguments to stack, and in x86-64 it also uses some specific registers and only after it the stack. That said, I don't understand why I get Segmentation fault while trying to print an integer (k and a are unused):

    global _main
    extern _printf
    section .data
format:  db "%d"
b:  dw 10
blen: equ $-b
lenlen: equ $-blen
k:  dw 6
    section .bss
a:  resw 1
    section .text
_main:
    sub rsp, 8
    mov rax, 0
    mov rdi, format
    mov rsi, b
    call _printf
    mov rax, 0x2000001
    mov rdi, 0
    syscall
Martian
  • 207
  • 1
  • 11
  • You also forgot to set `rdi` and `rax`. – Joseph Sible-Reinstate Monica Jun 07 '20 at 22:07
  • @JosephSible-ReinstateMonica thanks, now it works, but prints `8210` instead of `10`. Probably it has to do something with addresses (though it prints `8210` all the time, it doesn't change), but I don't understand why I can't use `lea` here (`lea rsi, [b]` gets me `Mach-O 64-bit format does not support 32-bit absolute addresses`). Also I have set the `rdi` and `rax`, I forgot to update the question. – Martian Jun 07 '20 at 22:11
  • @JosephSible-ReinstateMonica also could you explain why people declare variables like `msg: db "Hello World!", 10, 0`? I don't understand what `10` and `0` are for, I couldn't find information about it. Maybe it's connected. – Martian Jun 07 '20 at 22:15
  • `10` means `\n` and `0` is the NUL-terminator – Joseph Sible-Reinstate Monica Jun 07 '20 at 22:16
  • @JosephSible-ReinstateMonica when I change `format` from `"%d"`, which prints `8210`, to `"%d", 10, 0` it prints `8212`, and when I change it to `"%d", 0`, it prints nothing. Why? – Martian Jun 07 '20 at 22:19
  • For printing nothing, see https://stackoverflow.com/q/24093313/7509065 – Joseph Sible-Reinstate Monica Jun 07 '20 at 22:20
  • As for the wrong number, `printf` wants a value for %d, not an address, so do `[b]` instead of `b`. – Joseph Sible-Reinstate Monica Jun 07 '20 at 22:22
  • @JosephSible-ReinstateMonica when I change `mov rsi, b` to `mov rsi, [b]` it again says that `error: Mach-O 64-bit format does not support 32-bit absolute addresses`. – Martian Jun 07 '20 at 22:23
  • Put `default rel` at the top of your program. – Joseph Sible-Reinstate Monica Jun 07 '20 at 22:25
  • @JosephSible-ReinstateMonica now it prints some address, and when I change `mov rsi, [b]` to `lea rsi, [b]` (which is probably equivalent to `mov rsi, b`), it prints `8212` again. So it's not about addresses, `8212` is an actual value it finds at `b`. Maybe it has to do something with numeral systems (hex/dex)? – Martian Jun 07 '20 at 22:27
  • `dw` means 16-bit but `%d` means 32-bit. Either use `dd` instead of `dw`, or `%hd` instead of `%d`. – Joseph Sible-Reinstate Monica Jun 07 '20 at 22:29
  • @JosephSible-ReinstateMonica I think I start to lose my sanity. When I change `%d` to `%hd` it prints `8213`, and when I change it back to `%d` and declare `b` as `dd`, it prints `8212` again. – Martian Jun 07 '20 at 22:31
  • At this point, I'm afraid your code is too far gone from your original question for me to follow along. You should post a new question with your new problem. – Joseph Sible-Reinstate Monica Jun 07 '20 at 22:32
  • stdout is line buffered. With a raw `_exit` syscall, you can exit without giving stdio a change to flush buffers after a printf that didn't end with a newline. [Using printf in assembly leads to an empty ouput](https://stackoverflow.com/q/38379553). Don't do that; if you call printf, exit by calling exit(3) from libc. (or if you were writing a main instead of _start, returning from `main`) – Peter Cordes Jun 08 '20 at 03:11

1 Answers1

0

In this case, printf needs 2 parameters, a pointer to a format string (rdi), and the value (rsi).


That might need to be:

format  db      "%d",0         ;the 0 is needed
;       ...
        lea     rdi, format
rcgldr
  • 23,179
  • 3
  • 24
  • 50