用汇编语言将ascii / binary转换为十进制

时间:2016-06-15 06:45:04

标签: assembly binary x86 ascii

我想在汇编时将二进制数转换为小数,但我一直在零

这是数字

aLength     db  "00000000000000000000000000010101", NULL

我尝试使用此代码获取每个字符并按'0'乘以2并添加,但它一直说答案为0

mov rbx,aLength
mov dword[rsum],0
mov ecx,0
mov r10,32


lp: 
mov cl,byte[rbx]
sub cl,'0'
mov eax,dword[rsum]
mul dword[two]
add eax,ecx
mov dword[rsum],eax
add rbx,1
dec r10
cmp r10,0
jbe lp

mov r8d,dword[rsum]
mov byte[aLength],r8b

1 个答案:

答案 0 :(得分:4)

你的代码只循环一次,这是因为你颠倒了循环条件

cmp r10, 0
jbe lp

应该是

cmp r10, 0
ja lp

由于r10保留要转换的剩余位数 一旦你改变了那条代码就行了。

也就是说,它可以简化并且更具可读性 从二进制转换为十进制时使用的一个很好的技巧是使用进位标志。

换档指令将输出位(左移的lsb,右移的msb)放入进位标志。
使用rcl / rcr指令,我们可以抓取该位并将其移回另一个寄存器。

由于'1'的ASCII值是31h,这是奇数,因此设置了位0,'0'的ASCII值是30h,其中是偶数,因此有点0清楚;通过将数字ASCII值右移1,我们根据预期的数字值设置进位标志:0表示“0”,1表示“1”。
现在我们可以使用rcl将该位转换为eax

我也喜欢在可能的情况下使用整个寄存器,并在功能分离的代码段之间添加白线 最后,我将内存大小说明符(如WORD,DWORD,BYTE(适用时为PTR))大写,以便轻松识别内存操作。
还有一个:我删除了所有中间内存访问。

xor eax, eax           ;Converted value (so far)
mov rbx, aLength       ;Pointer to ASCII digits
mov r10, 32            ;Bits left to convert

_convert:
  movzx ecx, BYTE [rbx] ;Grab a digit
  add rbx, 1            ;And increment the pointer

  shr ecx, 1            ;Set CF according to the digit value
  rcl eax, 1            ;Shift CF into EAX from right (Rotate left)

  sub r10, 1            ;Decrement count
ja _convert

;Store results
mov DWORD [rSum], eax
mov BYTE [aLength], al