sdasdadas
sdasdadas

Reputation: 25096

How do I sys_write multiple ASCII characters on x64?

I am learning assembly and a number of guides explain how to sys_write but only using data stored in .text. I want to print multiple ASCII characters stored on the stack.

global _start

section .data

section .text

_start:
    push rbp
    mov rbp, rsp

    sub rsp, 16
    mov QWORD [rbp], 47
    mov QWORD [rbp - 8], 46
    
    mov rax, 1
    mov rdi, 1
    lea rsi, [rbp]
    mov rdx, 2
    syscall

    pop rbp
    
    mov rax, 60
    mov rdi, 0
    syscall

The above code sets up the stack frame (useless for the example), makes room for the local variables and places the ASCII characters for 47 and 46 on the stack. Then it loads the address to the first ASCII character into rsi and calls sys_write. Finally, it calls sys_exit.

However, when I run the code it only prints: /^@. Running strace produces the following output:

execve("./a.out", ["./a.out"], 0x7ffd1d1c2280 /* 60 vars */) = 0
write(1, "/\0", 2/\0)                      = 2
exit(0)                                 = ?
+++ exited with 0 +++

I feel like there's a fundamental misunderstanding I have concerning lea or [rbp] but I don't know enough assembly to know what I am missing.

Upvotes: 0

Views: 280

Answers (1)

possum
possum

Reputation: 2927

I'm assuming this is on linux or something linux-like, but your read is expecting a set of byte-packed chars, so the following change (keeping your 16 byte aligned stack)

    sub rsp, 16
    mov BYTE [rbp], 47
    mov BYTE [rbp-1], 46
    
    mov rax, 1
    mov rdi, 1
    lea rsi, [rbp-1]
    mov rdx, 2
    syscall

prints

./

Upvotes: 1

Related Questions