Last active
March 10, 2020 19:39
-
-
Save mrdmnd/ce844c7222884380831ab37d5ef9f59c to your computer and use it in GitHub Desktop.
Small Hello World repeater
This file contains hidden or 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
; nasm -f elf64 -g -F dwarf repeat_hello.asm && gcc -g -no-pie repeat_hello.o -o repeat_hello && ./repeat_hello 5 | |
; Intended for use on linux x86-864 machines; to run on OS X you'd have to change the syscalls. | |
extern atoi | |
global main | |
section .data | |
message: db "Hello, world!", 0x0A | |
length: equ 14 | |
err_msg: db "Wrong!", 0x0A | |
err_msg_len: equ 7 | |
section .text | |
main: push r12 ; Make an odd number of pushes to align stack to 16 byte boundary (call gives you one). | |
push r13 | |
push r14 | |
cmp rdi, 2 ; Argc goes into RDI. Test for two arguments, if not two, jump to error message. | |
jne error ; Jump to error if we don't have two arguments. | |
mov rdi, [rsi+8] ; Load the string at argv[1] (address [rsi+8]) into rdi - this should be the number of iterations. | |
; Note: argv[0] is at [rsi], but that's the name of the program, not the actual number of iters. | |
call atoi ; Convert the string stored at rdi to an integer in eax using the C library function atoi(). | |
; Make sure you use GCC and link against the C library. | |
cmp eax, 0 ; Gotta make sure that we have a positive number of times to print. | |
jl error ; If the value is too small, go to the error block. | |
; Now we're confident that EAX >= 0. | |
mov r15d, eax ; Set the iteration cap to EAX. | |
cmp r15, 0 ; Compare against zero. | |
je exit ; If the iteration cap is zero, go to exit; we've got no work to do. | |
mov r14, 0 ; Otherweise, we'll set a counter variable in r14 to zero. | |
display: ; Main "write" loop. Prints `message` zero or more times. | |
mov rax, 1 ; Set up syscall WRITE with it's magic number 1 on linux. | |
mov rdi, 1 ; We're writing to the special STDOUT file, so put it as the first parameter in RDI. | |
mov rsi, message ; Set RSI to address of message. | |
mov rdx, length ; Set RDX to length of message. | |
syscall ; Fire syscall for WRITE. | |
; Now we handle loop logic. | |
inc r14 ; Increment count variable, we've done a run through the code. | |
cmp r14, r15 ; Check if count is greater than the iteration threshold. | |
je exit ; If count = iters, we're done. Jump to exit label. | |
jmp display ; Otherwise, jump back to display label. | |
error: ; Print out "Wrong!" when we jump here. | |
mov rax, 1 | |
mov rdi, 1 | |
mov rsi, err_msg | |
mov rdx, err_msg_len | |
syscall | |
jmp exit | |
exit: ; Send EXIT syscall (different magic number than OS X) with return code zero. | |
mov rax, 60 | |
mov rdi, 0 | |
syscall |
Author
mrdmnd
commented
Mar 9, 2020
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment