2016-06-15 138 views
0

我想一個二進制數轉換爲裝配一個小數,但我不斷獲取零轉換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 
+2

看起來不錯對我來說,除了'MUL DWORD [二]'這是可疑的,可惜你沒有告訴我們「二」 ......由2乘法,嘗試'添加EAX,eax'(或一個'shl')而不是 – Tommylee2k

+0

看起來像x86程序集(幾乎每個CPU系列都有自己的程序集,不能一概而論)。 – MSalters

回答

4

你的代碼循環只有一次,這是因爲你倒上廁所平狀態

cmp r10, 0 
jbe lp 

應該

cmp r10, 0 
ja lp 

由於r10舉行位轉換的剩餘數量。
一旦您更改該行,您的代碼就可以工作。


也就是說,它可以被簡化並且更易讀。
從二進制轉換爲十進制時使用的一個很好的技巧是使用進位標誌。

移位指令將輸出位(左移lsb,右移msb)放入進位標誌。
使用rcl/rcr指令,我們可以獲取該位並將其移回另一個寄存器。

由於用於「1」是31H,這是奇數的ASCII值,因此具有位0組,以及用於「0」是30H,這是偶數,因此具有ASCII值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