atoi - Convert Strings to Numbers in x86 Assembly

Use the atoi_asm procedure to convert a C-string to an integer (ASCII to int). To convert a number to a C-string use itoa_asm (int to ASCII).

TITLE 'extern "C" int atoi_asm(const char *sz);'
.686

.model FLAT

PUBLIC	_atoi_asm

_ALPHATOINT	SEGMENT
_atoi_asm	PROC NEAR


	mov  edx, DWORD PTR [esp+4] ; sz

label1:

; skip white space

	mov  al, BYTE PTR [edx]
	cmp  al, 32 ; ' '
	je   SHORT label2
	cmp  al, 9  ; '\t'
	je   SHORT label2
	cmp  al, 13 ; '\r'
	je   SHORT label2
	cmp  al, 10 ; '\n'
	jne  SHORT label3

label2:

	inc  edx
	jmp  SHORT label1
	
label3:

	xor  ecx, ecx
	mov  cl, BYTE PTR [edx]
	inc  edx
	push esi

	cmp  ecx, 45 ; '-'
	mov  esi, ecx
	je   SHORT label4
	cmp  ecx, 43 ; '+'
	jne  SHORT label5
	
label4:

	xor  ecx, ecx
	mov  cl, BYTE PTR [edx]
	inc  edx
	
label5:

	xor  eax, eax

	cmp  ecx, 48 ; '0'
	jl   SHORT label7
	
label6:

	cmp  ecx, 57 ; '9'
	jg   SHORT label7

	lea  eax, DWORD PTR [eax+eax*4]
	lea  eax, DWORD PTR [ecx+eax*2-48]

	xor  ecx, ecx
	mov  cl, BYTE PTR [edx]
	inc  edx
	cmp  ecx, 48 ; '0'
	jge  SHORT label6

label7:

	cmp  esi, 45 ; '-'
	pop  esi
	jne  SHORT label8
	neg  eax
	
label8:

	ret  0

_atoi_asm	ENDP
_ALPHATOINT	ENDS
END

Use the atoui_asm procedure to convert a C-string to an unsigned integer (ASCII to uint). To convert a positive number to a C-string, use uitoa_asm (uint to ASCII).

TITLE 'extern "C" unsigned int atoui_asm(char *sz);'
.686

.model FLAT

PUBLIC	_atoui_asm

_ALPHATOUINT	SEGMENT
_atoui_asm	PROC NEAR

	mov	 edx, DWORD PTR [esp+4] ; sz

label1:

; skip white space

	mov	 al, BYTE PTR [edx]
	cmp	 al, 32 ; ' '
	je	 SHORT label2
	cmp	 al, 9  ; '\t'
	je	 SHORT label2
	cmp	 al, 13 ; '\r'
	je	 SHORT label2
	cmp	 al, 10 ; '\n'
	jne	 SHORT label3
	
label2:

	inc	 edx
	jmp	 SHORT label1
	
label3:

	xor	 ecx, ecx
	mov	 cl, BYTE PTR [edx]
	inc	 edx

	cmp	 ecx, 43 ; '+'
	jne	 SHORT label4

	xor	 ecx, ecx
	mov	 cl, BYTE PTR [edx]
	inc	 edx

label4:

	xor	 eax, eax

	cmp	 ecx, 48 ; '0'
	jl	 SHORT label6
	
label5:

	cmp	 ecx, 57 ; '9'
	jg	 SHORT label6

	lea	 eax, DWORD PTR [eax+eax*4]
	lea	 eax, DWORD PTR [ecx+eax*2-48]

	xor	 ecx, ecx
	mov	 cl, BYTE PTR [edx]
	inc	 edx
	cmp	 ecx, 48 ; '0'
	jge	 SHORT label5
	
label6:

	ret	 0
	
_atoui_asm	ENDP
_ALPHATOUINT	ENDS
END

Convert hexadecimal string to unsigned integer with the hextoui_asm procedure. To create a hexadecimal string from a number use uitoa_asm.

TITLE 'extern "C" unsigned int hextoui_asm(const char *sz);'
.686

.model FLAT

PUBLIC	_hextoui_asm

_HEXTOUINT	SEGMENT
_hextoui_asm PROC NEAR

	mov  edx, DWORD PTR [esp+4]

label1:

; skip whitespace

	mov  al, BYTE PTR [edx]
	cmp  al, 32 ; ' '
	je   SHORT label2
	cmp  al, 9  ; '\t'
	je   SHORT label2
	cmp  al, 13 ; '\r'
	je   SHORT label2
	cmp  al, 10 ; '\n'
	jne  SHORT label3

label2:

	inc  edx
	jmp  SHORT label1

label3:

	xor  ecx, ecx
	mov  cl, BYTE PTR [edx]
	inc  edx

	cmp  ecx, 43 ; '+'
	jne  SHORT label4

	xor  ecx, ecx
	mov  cl, BYTE PTR [edx]
	inc  edx
	
label4:

	xor  eax, eax
	test ecx, ecx ; check for 0 terminating character
	je   SHORT label9
	
label5:

	cmp  ecx, 48 ; '0'
	jl   SHORT label6
	cmp  ecx, 57 ; '9'
	jg   SHORT label6

; ECX contains the character and EAX the return value
; left shift by 4 bits is the same as multiplying by 16
; then add ECX to EAX since ECX is a hexadecimal character
	add  eax, 0ffffffdH
	shl  eax, 4
	add  eax, ecx

	jmp  SHORT label8
	
label6:


	cmp  ecx, 97 ; 'a'
	jl   SHORT label7
	cmp  ecx, 102 ; 'f'
	jg   SHORT label7

	sub  ecx, 32 ; 'a' - 'A' = 32

label7:

	cmp  ecx, 65 ; 'A'
	jl   SHORT label8
	cmp  ecx, 70 ; 'F'
	jg   SHORT label8

	shl  eax, 4 ; multiply by 16
	lea  eax, DWORD PTR [eax+ecx-55] ; 10 - 'A' = -55
	
label8:

	xor  ecx, ecx
	mov  cl, BYTE PTR [edx]
	inc  edx
	test ecx, ecx ; check for 0 terminating character
	jne  SHORT label5

label9:

	ret  0
	
_hextoui_asm ENDP
_HEXTOUINT	ENDS
END