当我去除法时,它给了我一些来自这个世界的答案。这样做是可行的:
mov ax, 11
mov bl, 37
div bl
mov [bAns16], ah
会给出11的正确余数。但一旦我将这些数字转换为变量,整个过程就会中断:
mov ax, [bNum1]
mov bl, [bNum4]
div bl
mov [bAns16], ah
;bNum1 = 11
;bNum4 = 37
答案应该是0,剩下的11,但答案最终是104,剩余的3。
而且,我对使用imul有问题--完全没有道理。与div相同:
mov ax, 33
mov bx, -17
imul ax, bx
mov [wAns15], ax
会给我正确的答案,但当我把变量放进去的时候,就不会马上给我答案:
mov ax, [bNum5]
mov bx, [bNum6]
imul ax, bx
mov [wAns15], ax
;bNum5 = 33
;bNum6 = -17
因此,它应该等于-561,但给我-32049,而不是一贯。
我做错了什么?谢谢!
编辑:
以下是数字声明:
bNum1 db 11
bNum2 db 15
bNum3 db 26
bNum4 db 37
bNum5 db 33
bNum6 db -17
bNum7 db -29
bNum8 db -40
发布于 2020-01-30 23:00:04
答案应该是0,剩余的是11,但最终答案是104,其余的是3。
这意味着AX
在div
指令之前包含了0x0F0B
值,而不是0x000B
。
张先生的评论暗示了这样做的原因:
与高级编程语言(如C)不同,汇编语言是用来直接告诉CPU该做什么的。
因此,应由程序员来确保数据类型的正确使用。
您的“变量”bNum1
只有一个字节长。这将是C编程语言中的unsigned char
类型的变量。
然而,指令mov ax, [bNum1]
将访问内存中的两个字节值.这等于C中的数据类型unsigned short
。
此指令将将存储在地址 bNum1
中的两个字节和该地址后面的地址解释为一个16位数字。
地址bNum1
的字节为11,地址后面的字节(bNum2
)为15;这两个字节将被解释为0xF0B
。
做什么
W. Chang已经建议使用dw
而不是db
。
在C编程语言中,这将使变量bNum1
的数据类型从unsigned char
更改为unsigned short
。
但是,您可能不想更改数据类型。
在这种情况下,需要将8位数字转换为16位数字:
对于无符号数字,只需将高8位设置为零即可。
对于有符号的数字,x86 CPU有名为cbw
(8到16位)和cwd
(16至32位)的指令。不幸的是,这只适用于AX
寄存器。
下面的示例演示如何将AL
中的8位数字转换为AX
中的16位数字。
未签署:
mov al, [bNum1]
mov ah, 0
签名:
; You want to load bNum6 to BX ...
mov al, [bNum6]
cbw
mov bx, ax
; ... and bNum5 to AX
mov al, [bNum5]
cbw
发布于 2020-01-30 22:38:34
AX
和BX
是16位寄存器.mov ax, [bNum1]
将从bNum1
读取16位(两个字节)。但是由于[bNum1]
(0x0B
)只有一个字节,所以它也会将[bNum2]
(0x0F
)作为高字节进行读取。因此,在mov ax, [bNum1]
AX
之后不是11
,而是3851
(0x0F0B
)。
https://stackoverflow.com/questions/59997884
复制相似问题