我在使用汇编程序解决此表达式时遇到了一些问题。
`$`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 )
答案 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。