Code:
~/.../examples/assembler >>> ./bighex2dec
ffffffffffffffffffffffffffffffff
32
ffffffff ffffffff ffffffff ffffffff
~/.../examples/assembler >>> cat bighex2dec.asm [40]
format elf64
extrn printf
extrn puts
extrn toupper
public main
section '.text' executable
main:
call init
xor eax,eax ; sys_read
xor edi,edi ; STDIN
mov rsi,inbuf
mov edx,hlength
syscall
mov r8,inbuf
cmp byte[r8+rax-1],10
jne .skipdec
dec rax
.skipdec:
mov r8,ilength
mov [r8],rax
mov rdi,fmt1
mov rsi,rax
xor eax,eax
call plt printf
; convert to uppercase
mov r8,ilength
mov r12,[r8]
mov rbx,inbuf
.L0:
test r12,r12
jz .exitL0
mov dil,[rbx]
call plt toupper
mov [rbx],al
inc rbx
dec r12
jmp .L0
.exitL0:
; copy to end of hexbuf
mov rdx,hlength
mov r8,ilength
sub rdx,[r8]
mov rsi,inbuf
mov r9,hexbuf
lea rdi,[r9+rdx]
mov rcx,[r8]
rep movsb
; convert to 4 dwords
mov rsi,hexbuf
mov rdi,number
mov r8,4
.L2:
mov rcx,8
.L1:
movzx ebx,byte[rsi]
shl edx,4
mov r9,table
movzx eax,byte[r9+rbx]
or edx,eax
inc rsi
dec rcx
jnz .L1
mov [rdi],edx
add rdi,4
dec r8
jnz .L2
mov rdi,fmt
mov r8,number
mov esi,[r8]
mov edx,[r8+4]
mov ecx,[r8+8]
mov r8d,[r8+12]
xor eax,eax
call plt printf
call cvt2dec
mov rdi,result
call plt puts
ret
init:
mov r8,table
mov byte[r8+'A'],10
mov byte[r8+'B'],11
mov byte[r8+'C'],12
mov byte[r8+'D'],13
mov byte[r8+'E'],14
mov byte[r8+'F'],15
mov byte[r8+'1'],1
mov byte[r8+'2'],2
mov byte[r8+'3'],3
mov byte[r8+'4'],4
mov byte[r8+'5'],5
mov byte[r8+'6'],6
mov byte[r8+'7'],7
mov byte[r8+'8'],8
mov byte[r8+'9'],9
ret
cvt2dec:
; this is code that converts 4 dwords
; to decimal text
mov rdi,result
add rdi,256
; mov rdi,result+256 ; write backwards
mov r10d,10
mov r9,1
.L0:
mov rbx,number
xor edx,edx
xor r8,r8
mov ecx,4
.L1:
mov eax,[rbx]
div r10d
mov [rbx],eax
test eax,eax
cmovnz r8,r9
add rbx,4
dec ecx
jnz .L1
add dl,'0'
dec rdi
mov [rdi],dl
cmp r8,1
je .L0
; place at begining of result
mov rcx,rdi
mov r8,result
sub rcx,r8
lea rsi,[r8+rcx]
mov rdi,result
mov r8,256
sub r8,rcx
mov rcx,r8
rep movsb
mov byte[rdi],0
ret
section '.data' writeable
inbuf db 32 dup(0)
hexbuf db 32 dup(0)
hlength = $-hexbuf
table db 256 dup(0)
result db 256 dup(0)
fmt db '%x %x %x %x',0xa,0
fmt1 db '%ld',0xa,0
section '.bss' writeable
number rd 4
ilength rq 1
~/.../examples/assembler >>> fasm
flat assembler version 1.72
usage: fasm <source> [output]
optional settings:
-m <limit> set the limit in kilobytes for the available memory
-p <limit> set the maximum allowed number of passes
-d <name>=<value> define symbolic variable
-s <file> dump symbolic information for debugging
~/.../examples/assembler >>> fasm bighex2dec.asm
flat assembler version 1.72 (16384 kilobytes memory)
3 passes, 2472 bytes.
~/.../examples/assembler >>> gcc bighex2dec.o -o bighex2dec
~/.../examples/assembler >>> ./bighex2dec
ffffffffffffffffffffffffffffffff
32
ffffffff ffffffff ffffffff ffffffff
~/.../examples/assembler >>> cat bighex2dec.asm [40]
format elf64
extrn printf
extrn puts
extrn toupper
public main
section '.text' executable
main:
call init
xor eax,eax ; sys_read
xor edi,edi ; STDIN
mov rsi,inbuf
mov edx,hlength
syscall
mov r8,inbuf
cmp byte[r8+rax-1],10
jne .skipdec
dec rax
.skipdec:
mov r8,ilength
mov [r8],rax
mov rdi,fmt1
mov rsi,rax
xor eax,eax
call plt printf
; convert to uppercase
mov r8,ilength
mov r12,[r8]
mov rbx,inbuf
.L0:
test r12,r12
jz .exitL0
mov dil,[rbx]
call plt toupper
mov [rbx],al
inc rbx
dec r12
jmp .L0
.exitL0:
; copy to end of hexbuf
mov rdx,hlength
mov r8,ilength
sub rdx,[r8]
mov rsi,inbuf
mov r9,hexbuf
lea rdi,[r9+rdx]
mov rcx,[r8]
rep movsb
; convert to 4 dwords
mov rsi,hexbuf
mov rdi,number
mov r8,4
.L2:
mov rcx,8
.L1:
movzx ebx,byte[rsi]
shl edx,4
mov r9,table
movzx eax,byte[r9+rbx]
or edx,eax
inc rsi
dec rcx
jnz .L1
mov [rdi],edx
add rdi,4
dec r8
jnz .L2
mov rdi,fmt
mov r8,number
mov esi,[r8]
mov edx,[r8+4]
mov ecx,[r8+8]
mov r8d,[r8+12]
xor eax,eax
call plt printf
call cvt2dec
mov rdi,result
call plt puts
ret
init:
mov r8,table
mov byte[r8+'A'],10
mov byte[r8+'B'],11
mov byte[r8+'C'],12
mov byte[r8+'D'],13
mov byte[r8+'E'],14
mov byte[r8+'F'],15
mov byte[r8+'1'],1
mov byte[r8+'2'],2
mov byte[r8+'3'],3
mov byte[r8+'4'],4
mov byte[r8+'5'],5
mov byte[r8+'6'],6
mov byte[r8+'7'],7
mov byte[r8+'8'],8
mov byte[r8+'9'],9
ret
cvt2dec:
; this is code that converts 4 dwords
; to decimal text
mov rdi,result
add rdi,256
; mov rdi,result+256 ; write backwards
mov r10d,10
mov r9,1
.L0:
mov rbx,number
xor edx,edx
xor r8,r8
mov ecx,4
.L1:
mov eax,[rbx]
div r10d
mov [rbx],eax
test eax,eax
cmovnz r8,r9
add rbx,4
dec ecx
jnz .L1
add dl,'0'
dec rdi
mov [rdi],dl
cmp r8,1
je .L0
; place at begining of result
mov rcx,rdi
mov r8,result
sub rcx,r8
lea rsi,[r8+rcx]
mov rdi,result
mov r8,256
sub r8,rcx
mov rcx,r8
rep movsb
mov byte[rdi],0
ret
section '.data' writeable
inbuf db 32 dup(0)
hexbuf db 32 dup(0)
hlength = $-hexbuf
table db 256 dup(0)
result db 256 dup(0)
fmt db '%x %x %x %x',0xa,0
fmt1 db '%ld',0xa,0
section '.bss' writeable
number rd 4
ilength rq 1
~/.../examples/assembler >>> fasm
flat assembler version 1.72
usage: fasm <source> [output]
optional settings:
-m <limit> set the limit in kilobytes for the available memory
-p <limit> set the maximum allowed number of passes
-d <name>=<value> define symbolic variable
-s <file> dump symbolic information for debugging
~/.../examples/assembler >>> fasm bighex2dec.asm
flat assembler version 1.72 (16384 kilobytes memory)
3 passes, 2472 bytes.
~/.../examples/assembler >>> gcc bighex2dec.o -o bighex2dec