extern NR_write extern strlen extern strcat section .rodata NL db 0xA section .bss printfBuff resb 4096 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 ;sub rsp, 8 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 cmp byte [rdi+1], 'd' je .rep_d cmp byte [rdi+1], 's' je .rep_s .rep_d: ;TODO jmp .continue .rep_s: push rdi ;mov byte [r11], 's' ;%s => Ss 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 ; rsp + 6*8 : RIP to printf call (+1), PUSH rbp,r12,r13,rdi (+4), +1 should be tS6 mov rsi, qword [rsp + 5*8 + (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 ;add rsp, 8 pop r13 pop r12 leave ret