转换ASCII /二进制汇编语言为十进制 [英] convert ascii / binary to decimal in assembly language
问题描述
我想一个二进制数转换为装配一个小数,但我一直在得到零
这是多少
aLength DB00000000000000000000000000010101,NULL
和我试图用这个code度日'0'每个字符和胶层乘以2,添加,但它口口声声说,答案是0
MOV RBX,aLength
MOV DWORD [率R sum],0
MOV ECX,0
MOV r10,32
LP:
MOV CL,字节[RBX]
子的cl,'0'
MOV EAX,DWORD [率R sum]
MUL DWORD [二]
添加EAX,ECX
MOV DWORD [率R sum],EAX
加RBX,1
十二月R10
CMP r10,0
JBE LPMOV r8d,DWORD [率R sum]
MOV字节[aLength],R8B
您code循环只有一次,这是因为你的反向循环条件
CMP R10,0
JBE LP
应
CMP R10,0
JA LP
由于 R10
举行位的剩余数进行转换。结果
一旦更改了该行的code工作。
这就是说,它可以简化,并且更具可读性。结果
一个好的技巧,从二进制转换为十进制时使用的是用进位标志。
转移指令把输出位(LSB的一个左移,最高位为右移)到进位标志。结果
使用 RCL
/ RCR
指令,我们可以抓住该位和移位它放回另一个寄存器。
由于用于ASCII值的1的是部分31h,这是奇数,因此具有0位组,和用于ASCII值的 0 的是30小时,这甚至,因此有位清0;通过向右移动1位的ASCII值,我们根据设置进位标志做预期的数字值:为0,1为'1'0结果。
现在我们可以使用 RCL
来该位为 EAX
转移。
我也可以在使用全寄存器,并把code的功能分隔片之间的白线preFER。结果
最后,我利用内存大小修饰符如WORD,DWORD,BYTE(PTR如适用)刚刚轻松点的内存操作。结果
还有一个:我删除了所有中介内存访问
XOR EAX,EAX;转换价值(到目前为止)
MOV RBX,aLength;指针ASCII数字
MOV R10,32;位向左转换_兑换:
MOVZX ECX,BYTE [RBX];抢位
加RBX,1;并增加指针 SHR ECX,1;根据数字值设置CF
RCL EAX,1; CF移位到EAX右(左旋转) 子R10,1;递减计数
JA _convert;存储结果
MOV DWORD [RSUM],EAX
MOV BYTE [aLength],人
i wanted to convert a binary number to a decimal in assembly but i keep on getting zero
this is the number
aLength db "00000000000000000000000000010101", NULL
and i tried using this code to get each character and subbing by '0' multiplying by 2 and adding but it keeps saying that the answer is 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
Your code loops only once, this is because you inverted the looping condition
cmp r10, 0
jbe lp
Should be
cmp r10, 0
ja lp
Since r10
hold the remaining number of bits to convert.
Once you change that line your code works.
That said, it can be simplified and made more readable.
One nice trick to use when converting from binary to decimal is the use of the carry flag.
Shifting instruction put the output bit (the lsb for a left shift, the msb for a right shift) into the carry flag.
Using the rcl
/rcr
instruction we can grab that bit and shift it back into another register.
Since the ASCII value for '1' is 31h, which is odd, hence have bit 0 set, and the ASCII value for '0' is 30h, which is even, hence have bit 0 clear; by shifting the digit ASCII value right by 1 we set the carry flag according do the intended digit value: 0 for '0' and 1 for '1'.
Now we can use rcl
to shift that bit into eax
.
I also prefer using whole register when possible, and put white lines between functional separated pieces of code.
Finally I capitalize memory size specifiers like WORD, DWORD, BYTE (PTR where applicable) just to easily spot memory operations.
One more: I removed all the intermediary memory access.
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
这篇关于转换ASCII /二进制汇编语言为十进制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!