Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- global _start
- section .data
- format: db "%c %s", 10, 0
- string: db "love", 10, 0
- string_len: equ $ - string
- buf: resb 64d
- section .text
- %define NEXT_PARAM R8
- %define NEXT_FORMAT_SYMBOL RBP
- %define BUFFER_SIZE RBX
- %macro printf 1-* ;macro with undefined qty of params
- %rep %0 ;loop at all parameters
- %rotate -1 ;%1 now is the last parameter
- push %1 ;push last param into stack
- %endrep
- call handle
- %endmacro
- _start:
- xor BUFFER_SIZE, BUFFER_SIZE
- ;printf format, string, 3802, 100, '!', 127
- printf format, 'c', string
- ;------------------------------------------------------------\
- ;ENTRY:
- ;DESTR:
- ;------------------------------------------------------------|
- handle:
- mov NEXT_PARAM, RSP
- add NEXT_PARAM, 8 ;[NEXT_PARAM] now is the last pushed arg -- format address
- mov NEXT_FORMAT_SYMBOL, [NEXT_PARAM] ;NEXT_FORMAT_SYMBOL points to current format symbol
- add NEXT_PARAM, 8 ;NEXT_PARAM is current arg
- dec NEXT_FORMAT_SYMBOL
- next:
- inc NEXT_FORMAT_SYMBOL
- cmp byte [NEXT_FORMAT_SYMBOL], 0 ;program ends by 0-symbol in format string
- je end_program
- cmp byte [NEXT_FORMAT_SYMBOL], '%' ;if not '%' print source format symbol
- jne .simple
- inc NEXT_FORMAT_SYMBOL
- ;switch case
- cmp byte [NEXT_FORMAT_SYMBOL], '%' ;case %%
- je .simple
- cmp byte [NEXT_FORMAT_SYMBOL], 'c'
- je .print_char
- cmp byte [NEXT_FORMAT_SYMBOL], 's'
- je .print_string
- cmp byte [NEXT_FORMAT_SYMBOL], 'd'
- je .print_decimal
- cmp byte [NEXT_FORMAT_SYMBOL], 'b'
- je .print_binary
- cmp byte [NEXT_FORMAT_SYMBOL], 'o'
- je .print_octal
- cmp byte [NEXT_FORMAT_SYMBOL], 'x'
- je .print_hex
- .simple:
- mov RAX, [NEXT_FORMAT_SYMBOL]
- call to_buf
- jmp next
- .print_char:
- mov RAX, [NEXT_PARAM]
- add NEXT_PARAM, 8
- call to_buf
- jmp next
- .print_string:
- mov RSI, [NEXT_PARAM]
- add NEXT_PARAM, 8
- .str_loop:
- mov RAX, [RSI]
- cmp RAX, 0
- je next
- call to_buf
- inc RSI
- jmp .str_loop
- .print_decimal:
- mov RAX, [NEXT_PARAM]
- ;making the mask for last bit
- xor R9, R9
- inc R9
- shl R9, 31d
- ;looking for the sign of the number
- mov R10, [NEXT_PARAM]
- and R10, R9
- cmp R9, R10
- jne .positive_decimal
- ;print minus
- push RAX
- mov RAX, '-'
- call to_buf
- pop RAX
- ;get a positive value from negative
- not RAX
- inc RAX
- .positive_decimal:
- mov R9, 10d
- call print_number
- add NEXT_PARAM, 8
- jmp next
- .print_binary:
- call printf_symbols
- jmp next
- .print_octal:
- call printf_symbols
- jmp next
- .print_hex:
- call printf_symbols
- jmp next
- ;------------------------------------------------------------/
- ;------------------------------------------------------------\
- ;Prints a positive number
- ;ENTRY: R9 -- base
- ; RAX -- number to print
- ;------------------------------------------------------------|
- print_number:
- xor R10, R10 ;reversed value
- xor RDX, RDX
- xor RCX, RCX ;number of digits
- mov R11, RAX
- .reverse_loop:
- ;reverse digits in number
- mov RAX, R11
- div R9d
- shl R10, 4
- add R10, RDX
- mov R11, RAX
- inc RCX
- cmp R11, R9
- jae .reverse_loop
- shl R10, 4
- add R10, R11
- inc RCX
- .print_loop:
- mov RAX, R10
- and RAX, 1111b
- add RAX, '0'
- call to_buf
- shr R10, 4
- dec RCX
- cmp RCX, 0
- jne .print_loop
- ret
- ;------------------------------------------------------------/
- ;------------------------------------------------------------\
- ;Puts a symbol into buf
- ;ENTRY: RAX - char to put
- ;------------------------------------------------------------|
- to_buf:
- push RSI
- cmp BUFFER_SIZE, 64d
- jae from_buf
- mov RDI, buf
- add RDI, BUFFER_SIZE
- stosb
- inc BUFFER_SIZE
- pop RSI
- ret
- ;------------------------------------------------------------/
- ;------------------------------------------------------------\
- ;Prints a buffer's content on a screen
- ;------------------------------------------------------------|
- from_buf:
- push RDX
- push RSI
- cmp BUFFER_SIZE, 0
- je .quit
- mov RDX, BUFFER_SIZE
- mov RSI, buf
- call printf_symbols
- xor BUFFER_SIZE, BUFFER_SIZE
- .quit:
- pop RSI
- pop RDX
- ret
- ;------------------------------------------------------------/
- ;------------------------------------------------------------\
- ;ENTRY: RSI -- symbol address, RDX -- qty of symbols to print
- ;------------------------------------------------------------|
- printf_symbols:
- push RAX
- push RDI
- xor RAX, RAX
- inc RAX
- xor RDI, RDI
- inc RDI
- syscall
- pop RDI
- pop RAX
- ret
- ;------------------------------------------------------------/
- end_program:
- call from_buf
- mov RAX, 60
- xor RDI, RDI
- syscall
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement