Pelles C forum
Assembly language => Assembly discussions => Topic started by: Jokaste on November 10, 2017, 09:01:56 PM
-
Who will write the short function wich convert an hexadecimal string in RCX into a QWORD. If there is an error it returns 0.
I propose 66 bytes and 29 lines.
Hex2QWord :
[0000000140001420] 4531C0 xor r8d,r8d
[0000000140001423] 31C0 xor eax,eax
[0000000140001425] B237 mov dl,37
[0000000140001427] EB0A jmp 0000000140001433
[0000000140001429] 66666690 nop
[000000014000142D] 666690 nop
[0000000140001430] 4901C0 add r8,rax
[0000000140001433] 8A01 mov al,byte ptr [rcx]
[0000000140001435] 48FFC1 inc rcx
[0000000140001438] 84C0 test al,al
[000000014000143A] 7422 je 000000014000145E
[000000014000143C] 49C1E004 shl r8,4
[0000000140001440] 3C30 cmp al,30
[0000000140001442] 7C0E jl 0000000140001452
[0000000140001444] 3C39 cmp al,39
[0000000140001446] 7E12 jle 000000014000145A
[0000000140001448] 245F and al,5F
[000000014000144A] 3C41 cmp al,41
[000000014000144C] 7C04 jl 0000000140001452
[000000014000144E] 3C46 cmp al,46
[0000000140001450] 7E04 jle 0000000140001456
[0000000140001452] 4831C0 xor rax,rax
[0000000140001455] C3 ret
[0000000140001456] 28D0 sub al,dl
[0000000140001458] EBD6 jmp 0000000140001430
[000000014000145A] 240F and al,F
[000000014000145C] EBD2 jmp 0000000140001430
[000000014000145E] 4C89C0 mov rax,r8
[0000000140001461] C3 ret
-
Longer but 4 jumps removed.
[00000001400013B0] 56 push rsi
[00000001400013B1] 4531C0 xor r8d,r8d
[00000001400013B4] 31C0 xor eax,eax
[00000001400013B6] 31D2 xor edx,edx
[00000001400013B8] EB09 jmp 00000001400013C3
[00000001400013BA] 666690 nop
[00000001400013BD] 666690 nop
[00000001400013C0] 4901C0 add r8,rax
[00000001400013C3] 8A01 mov al,byte ptr [rcx]
[00000001400013C5] 4088C6 mov sil,al
[00000001400013C8] 48FFC1 inc rcx
[00000001400013CB] 84C0 test al,al
[00000001400013CD] 7429 je 00000001400013F8
[00000001400013CF] 49C1E004 shl r8,4
[00000001400013D3] 3C39 cmp al,39
[00000001400013D5] 660F4FC2 cmovg ax,dx
[00000001400013D9] 3C30 cmp al,30
[00000001400013DB] 660F4CC2 cmovl ax,dx
[00000001400013DF] 240F and al,F
[00000001400013E1] 75DD jne 00000001400013C0
[00000001400013E3] 4088F0 mov al,sil
[00000001400013E6] 245F and al,5F
[00000001400013E8] 3C46 cmp al,46
[00000001400013EA] 480F4FC2 cmovg rax,rdx
[00000001400013EE] 3C41 cmp al,41
[00000001400013F0] 480F4CC2 cmovl rax,rdx
[00000001400013F4] 2C37 sub al,37
[00000001400013F6] EBC8 jmp 00000001400013C0
[00000001400013F8] 5E pop rsi
[00000001400013F9] 4C89C0 mov rax,r8
[00000001400013FC] C3 ret
-
The previous code can be improved in replacing partial registers (al and sil) with the fill register.
Replace MOV AL,BYTE PTR [rcx] with MOVZX rax,BYTE PTR [rcx] and
Replace MOV SIL,AL with MOV RSI,rax and
Replace MOV AL,SIL with MOV RAX,RSI.
It becomes:
push rsi
xor r8d,r8d
xor eax,eax
xor edx,edx
jmp SHORT @Loop_0
; ==================================================================================
ALIGN 16
; ==================================================================================
@Loop :
or r8,rax
@Loop_0 :
movzx rax,BYTE PTR [rcx]
mov rsi,rax
inc rcx
test al,al
jz SHORT @EndLoop
shl r8,4
cmp al,'9'
cmovg ax,dx
cmp al,'0'
cmovl ax,dx
and al,0fh
jnz SHORT @Loop
mov rax,rsi
and al,5fh
cmp al,'F'
cmovg rax,rdx
cmp al,'A'
cmovl rax,rdx
sub al,37h
jmp SHORT @Loop
@EndLoop :
pop rsi
mov rax,r8
ret