-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: enrich comments on 01-hello.asm
- Loading branch information
Showing
1 changed file
with
50 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,64 @@ | ||
section .data | ||
msg db "Hello, World!" | ||
; We define the constant `msg`, the string to print. | ||
; We use the `db` (define byte) directive to define | ||
; constants of one or more bytes (1 char = 1 byte). | ||
msg db `Hello, World!\n` | ||
|
||
section .text | ||
global _start | ||
_start: | ||
; rax contains the syscall number. 1 means sys_write | ||
; We call the sys_write syscall to print on the | ||
; screen. Syscalls are invoked with `syscall` and | ||
; they are identified by a number. | ||
; | ||
; size_t sys_write(uint fd, const char* buf, size_t count) | ||
; The identifier for sys_write is 1. The `syscall` | ||
; intruction will look for the instruction id in the | ||
; register `rax`. So we move 1 in there. | ||
mov rax, 1 | ||
; rdi is how you pass the first argument | ||
; The system call to invoke has the signature: | ||
; | ||
; size_t sys_write(uint fd, const char* buf, size_t count) | ||
; The `syscall` instruction wants the first argument | ||
; in `rdi`. In this case, the first argument is the | ||
; file descriptor of where to write the output. | ||
; We will use 1, which identifies the standard output. | ||
mov rdi, 1 | ||
; rsi is the register for the second argument | ||
; The second argument is expected to be in `rsi` and | ||
; the signature tells us that it the string we want | ||
; to print. We defined the buffer in the .data section | ||
; (it's `msg`), so we just need to move it to `rsi` | ||
mov rsi, msg | ||
; rdx is the register for the third argument | ||
mov rdx, 13 | ||
; we're now finally issuing the syscall | ||
; `rdx` is the register for the third argument. | ||
; We see in the signature that this is the count of | ||
; characters we want to print. | ||
; | ||
; Note: the string is null-terminated, that is, there | ||
; is an ending "ghost" character we need to account for. | ||
mov rdx, 14 | ||
; We're now finally issuing the syscall | ||
syscall | ||
; syscall 60 is the exit syscall | ||
; | ||
; Now the message is printed! Time to exit the program. | ||
|
||
; Same as above, we invoke `syscall` with 60, which is | ||
; `exit` and has the following signature: | ||
; | ||
; void exit(int status) | ||
; Once again, `syscall` looks for the identifier in | ||
; `rax`. We move 60, the identifier for `exit`, there | ||
mov rax, 60 | ||
; rdi is the first argument | ||
; Again, `rdi` is where the first argument is expected | ||
; to be found. | ||
; The first argument is the status code (see signature) | ||
; so we put 0 for a clean exit. | ||
mov rdi, 0 | ||
; issuing the syscall | ||
; Issuing the `exit` syscall and cleanly exiting | ||
; the program | ||
syscall |