diff options
| author | Mikhail Osipov <mike.osipov@gmail.com> | 2019-10-12 00:23:50 +0300 |
|---|---|---|
| committer | Mikhail Osipov <mike.osipov@gmail.com> | 2019-10-12 00:23:50 +0300 |
| commit | 2d78510b9af6f70ec34d77f0e047c698bdf061a9 (patch) | |
| tree | f56f2c9d7c29952748d62aa99d6e8fdc76402ada /printf.s | |
| parent | 1248eae0617555a4f13f7bbee9f120ad3d46c5f3 (diff) | |
draftng
Diffstat (limited to 'printf.s')
| -rw-r--r-- | printf.s | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/printf.s b/printf.s new file mode 100644 index 0000000..3bb24ca --- /dev/null +++ b/printf.s @@ -0,0 +1,120 @@ +.include "lib.s" + +.macro bufpush + cmpq $bufend, %rdi + jle 9f + stosb + 9: +.endm + +.globl printf +printf: + prologue + + backup %rax, %rbx, %rcx, %rdx + backup %rsi, %rdi + + movq 16(%rbp), %rsi + leaq 24(%rbp), %rbx + movq $buf, %rdi + +.loop: + lodsb + testb %al, %al + jz .loopout + + cmpb $'%, %al + jne .append + + lodsb + testb %al, %al + jz .loopout + + cmpb $'%, %al + je .append + + cmpb $'s, %al + je .print_string + + cmpb $'d, %al + je .print_signed + + cmpb $'u, %al + je .print_unsigned + + jmp .loop + +.append: + bufpush + jmp .loop + +.print_string: + backup %rsi + + movq (%rbx), %rsi + addq $8, %rbx + jmp 2f + + 1: bufpush + 2: lodsb + testb %al, %al + jnz 1b + + restore %rsi + jmp .loop + +.print_signed: + movq (%rbx), %rax + addq $8, %rbx + + cmpq $0, %rax + jge 1f + + pushq %rax + movb $'-, %al + bufpush + popq %rax + negq %rax + + 1: + movq $10, %rcx + call .print_number + jmp .loop + +.print_unsigned: + movq (%rbx), %rax + addq $8, %rbx + + movq $10, %rcx + call .print_number + jmp .loop + +.print_number: + xorq %rdx, %rdx + divq %rcx + pushq %rdx + testq %rax, %rax + jz 1f + call .print_number + 1: + popq %rax + addq $'0, %rax + bufpush + ret + +.loopout: + movq %rdi, %rdx + subq $buf, %rdx + movq $buf, %rsi + movq $STDOUT, %rdi + sys write + + restore %rsi, %rdi + restore %rax, %rbx, %rcx, %rdx + + leave + ret + +.bss +.comm buf, 4096 +.comm bufend, 2 |
