我们有一个字符串,其偏移量为di。此proc将在ax中将其转换为整数。 proc将在0-999之间正常工作。但是例如对于1000或2343或其他大于1000的数字将不起作用。问题出在哪儿 ?我很困惑。 tlen也是我定义的临时字节。
atoi proc far
mov cl,len
mov ch,0
mov ah,0
start:
dec cl
jcxz addlastdigit
mov tlen,cl;save cl
mov al,1
mov bl,10
getMultiplier:
mul bl
Loop getMultiplier
mov cl,tlen ; retrive cl
mov dl,byte ptr[di]
sub dl,30h
mul dl
add num,ax
inc di
jmp start
addlastdigit:
mov ax,num
mov dl,byte ptr[di]
sub dl,30h
mov dh,0
add ax,dx
Ret
atoi endp
答案 0 :(得分:1)
那太可怕了:))
无论如何,它不起作用的直接原因是你使用8位乘法,特别是mul dl
。 mul bl
几乎不适用于1000,但10000以上也会失败。
一般建议:学会使用调试器逐步执行代码并查看出错的地方。
答案 1 :(得分:1)
问题是“mul dl”。 DL是一个8位寄存器,因此DL可以容纳的最大值是255.您可能正确地乘以100(例如“99 * 100 + 9 = 999”),然后不能乘以1000或更高。
代码需要使用更大的寄存器。代码也需要重写,以便每个字符只能执行一个MUL。
示例(NASM,未经测试):
atioi:
xor eax,eax
.nextChar:
movzx ebx,byte [di]
inc di
sub bl,'0'
jb .invalidChar
cmp bl,9
ja .invalidChar
lea eax,[eax*4+eax]
sub ecx,1
lea eax,[eax*2+ebx]
jne .nextChar
ret
.invalidChar:
; Not sure what you're planning to do with error handling..
上面的代码假定一个80386或更高版本的CPU(并且将以实模式或16位代码工作),并应处理高达“2 ** 32-1”(超过4)的值亿元)。
对于在您出生之前可能已经过时的80x86 CPU(80286及更早版本),您需要使用一对寄存器(例如DX:AX)而不是32位寄存器来获得相同的范围,或限制它结果小于65536并使用16位寄存器而不是32位寄存器(例如将EBX替换为BX,将EAX替换为AX等)。