atoi32 & atoiu32 模拟

; Prototype
;
eax atoui32(int *str)
;
Param
;
str: The address of ASCII null terminated string which express a unsigned number.
;
Flag
;
CF: is 1 if there are carry in.
;
Others: are unchanged.
;
Function own the stack.
;
Paramter push from left to right.
;
Conversion will stop when meets first ASCII character witch is not expresses a number.
atoui32 PROC NEAR32
; Save context
push ebp
mov ebp, esp
push ebx
push ecx
push edx
push esi
pushf

; Initialize
mov ebx, 0 ; Save sum.
mov ecx, 0 ; Save current ASCII character.
mov edx, 0 ; Multiplier and temporay result.
mov esi, [ebp + 8] ; Address of string which expresses a number.
cld ; Address increasing.

; Main process
while_atoui32:
mov eax, 0
lodsb ; Next ASCII character from left to right.

cmp al, '0' ; If al < '0'
jl exit_atoui32 ; Then jump out.
cmp al, '9' ; If al > '9'
jg exit_atoui32 ; Then jump out.
mov cl, al ; Save current ASCII character to 'cl'.

mov eax, ebx ; Multiplicand.
mov edx, 10 ; Multiplier.
mul edx ; Only 'eax' take effect.
jc error_carry_atoui32; Jump to error condition if carry in.
mov ebx, eax

sub cl, '0' ; ASCII to numberic.
add ebx, ecx ; Accumulate. Only 'cl' take effect.
jc error_carry_atoui32

jmp while_atoui32

exit_atoui32:
; Return from 'eax'
mov eax, ebx
; Restore context
popf
pop esi
pop edx
pop ecx
pop ebx
pop ebp
ret 4

error_carry_atoui32:
; Set FLAGS register
pop ax ; FLAGS => 'ax'.
or ax, 0000100000000001b ; CF and OF are set to 1 while others are unchanged.
push ax ; As FLAGS register.
mov eax, 0 ; Return value.
jmp exit_atoui32
atoui32 ENDP

; Prototype
;
eax atoi32(int *str)
;
Param
;
str: The address of ASCII null terminated string which express a signed number.
;
Flag
;
CF: is 1 if there are carry in.
;
Others: are unchanged.
;
Function own the stack.
;
Paramter push from left to right.
;
Conversion will stop when meets first ASCII character witch is not expresses a number.
;
This function depends on 'atoui32'
atoi32 PROC NEAR32
; Save context
push ebp
mov ebp, esp
push ebx
pushf

; Initialize
mov esi, [ebp + 8] ; Address of string which expresses a number.

; Main proccess
mov bl, [esi] ; If first character is a sign character.
cmp bl, '-' ; If 'bl' == '-' or 'bl' == '+'
je if_sign_atoi32
cmp bl, '+'
jne else_sign_atoi32
if_sign_atoi32:
inc esi ; Then skip for the first sign character('-' or '+').
else_sign_atoi32: ; Else call procedure 'atoui32'
push esi
call atoui32

cmp bl, '-' ; If string are negative number.
jne positive_atoi32
neg eax ; Then we get its 2's complement.
jns error_carry_atoi32
jmp exit_atoi32
positive_atoi32:
test eax, eax ; Else, the string are positive number.
js error_carry_atoi32

exit_atoi32:
; Restore context
popf
pop ebx
pop ebp
ret 4

error_carry_atoi32:
pop ax ; FLAGS => 'ax'.
or ax, 0000100000000001b ; CF and OF to 1 while others are unchanged.
push ax ; 'ax' as FLAGS.
mov eax, 0 ; Return value.
jmp exit_atoi32
atoi32 ENDP

  

posted @ 2011-09-14 19:15  walfud  阅读(486)  评论(0编辑  收藏  举报