extern NR_write extern strlen extern strcat extern itoa section .rodata NL db 0xA section .bss printfBuff resb 4096 printfNBuff resb 32 section .text global print global puts global printf ;----- print (char* string) -----; ; return value: N/A print: push rbp mov rbp, rsp call strlen mov rdx, rax mov rax, NR_write mov rsi, rdi mov rdi, 1 syscall leave ret ;----- puts (char* string) -----; ; return value: N/A puts: push rbp mov rbp, rsp mov r10, rdi call print mov rdi, r10 mov rax, NR_write mov rdi, 1 mov rsi, NL mov rdx, 1 syscall leave ret ;----- printf(const char* string, ...) -----; printf: push rbp mov rbp, rsp push r12 push r13 xor r10, r10 lea r11, [rel printfBuff] .makeStr: cmp byte [rdi], 0x0 je .finish cmp byte [rdi], '%' je .replaceArg mov r12b, byte [rdi] mov byte [r11], r12b jmp .continue .replaceArg: cmp byte [rdi+1], 0x0 je .continue push rdi cmp byte [rdi+1], 'd' je .rep_d cmp byte [rdi+1], 's' je .rep_s ;--- %d ---; .rep_d: cmp r10, 0 je .rep_d_rsi cmp r10, 1 je .rep_d_rdx cmp r10, 2 je .rep_d_rcx cmp r10, 3 je .rep_d_r8 cmp r10, 4 je .rep_d_r9 ;get from stack mov rsi, qword [rbp + 16 + (r10-5)*8] jmp .convertInt .rep_d_rsi: mov rdi, rsi jmp .convertInt .rep_d_rdx: mov rdi, rdx jmp .convertInt .rep_d_rcx: mov rdi, rcx jmp .convertInt .rep_d_r8: mov rdi, r8 jmp .convertInt .rep_d_r9: mov rdi, r9 .convertInt: lea rsi, [rel printfNBuff] push rcx push rdx push r8 push r10 push rsi call itoa pop rsi pop r10 pop r8 pop rdx pop rcx mov rsi, rax jmp .sinsertLoop ;--- %s ---; .rep_s: cmp r10, 0 je .sinsertLoop ;nothing to do, rsi already correct cmp r10, 1 je .rep_s_rdx cmp r10, 2 je .rep_s_rcx cmp r10, 3 je .rep_s_r8 cmp r10, 4 je .rep_s_r9 ;get from stack mov rsi, qword [rbp + 16 + (r10-5)*8] jmp .sinsertLoop .rep_s_rdx: mov rsi, rdx jmp .sinsertLoop .rep_s_rcx: mov rsi, rcx jmp .sinsertLoop .rep_s_r8: mov rsi, r8 jmp .sinsertLoop .rep_s_r9: mov rsi, r9 .sinsertLoop: cmp byte [rsi], 0x0 je .s0f mov r13b, byte [rsi] mov byte [r11], r13b inc rsi inc r11 jmp .sinsertLoop .s0f: inc r10 pop rdi add rdi, 2 jmp .makeStr .continue: inc rdi inc r11 jmp .makeStr .finish: mov byte [r11], 0x0 lea rdi, [rel printfBuff] call print pop r13 pop r12 leave ret