开发者

assembly atoi dizzy error

开发者 https://www.devze.com 2023-02-03 22:52 出处:网络
We have a string which its offset is in di. This proc will convert it to integer in ax. The proc will work good for 0-999. but for example for 1000 or 2343 or other numbers greater Than 1000 will not

We have a string which its offset is in di. This proc will convert it to integer in ax. The proc will work good for 0-999. but for example for 1000 or 2343 or other numbers greater Than 1000 will not work. where is the problem ? I have confused. also tlen is temp byte that i have defined.

 at开发者_高级运维oi 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


The problem is "mul dl". DL is an 8-bit register, so the maximum value DL can hold is 255. You probably multiply by 100 correctly (e.g. "99*100+9 = 999), then fail to multiply by 1000 or higher.

The code needs to use larger registers. The code also needs to be rewritten so that it only does one MUL per character.

Example (NASM, untested):

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..

The code above assumes an 80386 or later CPU (and will work in real mode or 16-bit code), and should handle values up to "2**32-1" (over 4 billion) properly.

For 80x86 CPUs that were probably obsolete before you were born (80286 and older) you'd need to use a pair of registers (e.g. DX:AX) instead of 32-bit registers to get the same range, or limit it to results that are less than 65536 and use 16-bit registers instead of the 32-bit registers (e.g. replace EBX with BX, EAX with AX, etc).


That's quite horrible :)

Anyway, the immediate reason why it doesn't work is that you are using 8 bit multiplies, in particular, the mul dl. The mul bl barely happens to work for 1000, but will also fail for 10000 and above.

General advice: learn to use a debugger to step through your code and see where it goes wrong.

0

精彩评论

暂无评论...
验证码 换一张
取 消