在汇编程序中将单词转换为双字

时间:2012-11-05 13:50:48

标签: windows assembly coding-style

我在使用汇编程序解决此表达式时遇到了一些问题。

`$`z=(5*a-b/7)/(3/b+a*a) 

我想知道如何将单词转换成双字(unsigned solution),
我是否必须使用cwb命令或使用AX:BX,如果我必须使用那些最后的寄存器,
 我该如何正确编写命令?

我将在DosBox下测试Turbo Debugger中的代码。 我的完整代码

assume cs:code,ds:data 
data segment
;
a db ?
b db ?
rez dw ?
;
data ends
;
code segment
;
mov ax,data
mov ds,ax
;
;
;#####prima paranteza
;
mov al,a    ;ah=a
mul 5       ;ax=a*5
mov cx,ax   ;cx=ax
mov ah,b    ; il mut pe ah in b  ( pregatire pt conversie fara semn )
mov al,0    ; l-am convertit pe b in word ( pe 2 octeti )
div 7       ; am impartit double word-ul b la 7 , catul a ramas in ah , restul a ramas in al 
sub cx,ax   ; (am tinut cont de faptul ca in ax a ramas rezultatul dupa impartire )  , cx=cx-ax, a*5 - b/7
;
; ####a 2 a paranteza
;
mov ah,3    
mov al,0    ; conversie de la b la w  ( fara semn )
div b       ; ax=3/b
mov bx,ax   ; bx = ax
mov al,a    
mul a       ; ax = a * a 
add ax,bx   ; ax = ax + bx
;
;
; #### calcul final 
mov bx,ax   ; bx = ax ( rezultatul celei de a 2 a paranteze )
mov ax,cx   ; ax = cx ( rezultatul primei paranteze )

4 个答案:

答案 0 :(得分:1)

字到双字?

让我们看看我是否得到了你:

字 - > 8位
双字 - > 16位

AX,BX,CX和DX是16位寄存器,它们由另外两个8位寄存器[ABCD] H和[ABCD] L构成,因此,AX将是:

AH AL
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | - | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |

当您使用AX时,您同时使用这两个。因此,如果要将一个字转换为双字,只需清除整个[ABCD] X寄存器,然后将字移动到[ABCD] L寄存器,将[ABCD] X保留为字值。

干杯

答案 1 :(得分:0)

嗯,最糟糕的情况是将双字清零,然后将字复制到双字的下半部分(第一个0-x位/我的汇编程序生锈)。可能有更有效的方法来做到这一点,我承认

答案 2 :(得分:0)

首先,变量的范围是多少?它们都是未签名的(或者其中一些是签名的)?

其次,您需要什么样的准确度;以及如何影响由于整数除法中的舍入导致的精度损失等问题?

第三,表现有多重要?内存使用有多重要?

第四,有哪种“CPU类型”限制?它是“仅8086”(你不能使用32位寄存器),还是“80386或更高版本”(你可以在16位代码中使用32位寄存器)?你能用浮点和FPU吗?

根据以上所有情况,生成的代码可能如下所示:

; Assumes a ranges from 0 to 7
; Assumes b ranges from 1 to 1234
; Assumes 80386 or later
; Note: requires a pre-computed 19728-byte lookup table

    movzx eax,word a
    movzx ebx,word b
    lea eax,[0xFFFFFFF8 + ebx*8+eax]
    mov ax,[myTable + eax*2]

当然,根据以上所有情况,结果代码也可能完全不同......

答案 3 :(得分:0)

通常在16位模式下使用DX:AX完成。您可以使用CWD将AX签名扩展为DX,或者您可以清除DX。