; We need to tell it about main when using c lib functions ; else it will complain about it during linking global main ; c library symbols for the compiler (linker doesn't care) extern printf extern atoi section .data ; Strings to printf' fmt: db '%d + %d = %d',0xA,0x0 ; append with newline and null terminator usageMsg: db 'usage: %s first_number second_number',0xA,0x0 section .text ; Note that this will be called by some external function (actually, ; the compiler will generate its own _start that eventually calls this) main: push rbp mov rbp, rsp push rbx push r12 push r13 push r14 push r15 ; main takes an int and a char pointer as arguments mov r12, rdi mov r13, rsi ; This segfaults when moved below the line "jne .fail" ; Why? ; Because it stores the float registers on the stack ; as well. This doesn't seem to be particularly well ; documented. sub rsp, 8 ; allocate 8 bytes = 2 integers cmp r12, 3 ; argc == 3 jne .fail mov rdi, qword [r13 + 8] ; argv[1] call atoi mov dword [rsp], eax ; store integer 1 mov rdi, qword [r13 + 16] ; argv[2] call atoi mov dword [rsp + 4], eax ; store integer 2 ; add the two numbers mov ecx, dword [rsp] add ecx, dword [rsp + 4] ; print the result mov rdi, fmt mov esi, [rsp] mov edx, [rsp + 4] call printf ; main returns an integer xor rax, rax jmp .end .fail: mov rdi, usageMsg mov rsi, [r13] ; argv[0] = the executable name call printf mov rax, 1 .end: pop r15 pop r14 pop r13 pop r12 pop rbx mov rsp, rbp pop rbp ret