2

This is my NASM code from wiki. I compile it with below command in MacOS 10.12.6.

nasm -f macho64 -o echo.o echo.asm
ld echo.o -e _start -o echo

I run the program with:

./echo

I found the out string does not print. I use lldb to debug it, found the address that deliver to syscall is not the out string's actual address.(actual address is 0x2013, delivered address is 0x2026) So it prints an empty string. NASM's version is 2.13.02. Can someone explain why this happening and how I can fix it?

global _start

section .data

query_string:       db  "Enter a character:  "
query_string_len:   equ $ - query_string
out_string:         db  "You have input:  "
out_string_len:     equ $ - out_string

section .bss

in_char:            resw 4

section .text

_start:

mov rax, 0x2000004      ; put the write-system-call-code into register rax
mov rdi, 1              ; tell kernel to use stdout
mov rsi, query_string   ; rsi is where the kernel expects to find the address of the message
mov rdx, query_string_len   ; and rdx is where the kernel expects to find the length of the message 
syscall

; read in the character
mov rax, 0x2000003      ; read system call
mov rdi, 0              ; stdin
mov rsi, in_char        ; address for storage, declared in section .bss
mov rdx, 2              ; get 2 bytes from the kernel's buffer (one for the carriage return)
syscall

; show user the output
mov rax, 0x2000004      ; write system call
mov rdi, 1              ; stdout
mov rsi, out_string
mov rdx, out_string_len
syscall

mov rax, 0x2000004      ; write system call
mov rdi, 1              ; stdout
mov rsi, in_char
mov rdx, 2              ; the second byte is to apply the carriage return expected in the string
syscall

; exit system call
mov rax, 0x2000001      ; exit system call
xor     rdi, rdi
syscall
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
BrianChen
  • 183
  • 10
  • I think this is a bug about nasm. I use nasm which it's version is 2.10 then everything all right. – BrianChen Feb 01 '18 at 06:59
  • Is the version that doesn't work 2.11.08? – Michael Petch Feb 01 '18 at 07:00
  • @MichaelPetch The version 2.13.02 doesn't work. But the version 2.10 work. I didn't try the version 2.11.08. – BrianChen Feb 01 '18 at 07:10
  • 1
    Looks like it screwed up the absolute memory addresses. You may be able to use RIP relative addressing (position independent) which is the norm for more recent MacOS. At the top of your assembly file add `default rel` and then for each on of the memory addresses change them from `mov rsi, in_char` to `lea rsi, [in_char]`. Do this for all the other addresses (convert from MOV to LEA) – Michael Petch Feb 01 '18 at 07:45
  • 1
    @MichaelPetch Amazing, it worked. Thank you very much. I puzzle about this problem for a long time. – BrianChen Feb 01 '18 at 08:06
  • 1
    It is as you suggest still a NASM bug. (2.13.02) The absolute memory location calculation.seems screwed up. RIP Relative addressing on MacOS though is usually preferable nonetheless. – Michael Petch Feb 01 '18 at 08:08
  • @MichaelPetch that's a perfectly valid answer, why only put it in a comment? – Kamil.S Feb 11 '18 at 09:22
  • @Kamil.S : Someone else had the exact same issue. I wrote an answer to their question, and think we should mark this one as a duplicate – Michael Petch Mar 12 '18 at 00:39

0 Answers0