我正在使用x86 Assembly,我遇到了使用MUL
指令的需要。
我的代码片段过去是这样的:
mov al, <some_number>
mul bl
add al, [edi]
mov [edi], al
其中<代码>
所以我的程序正在命中未定义的行为,在这种情况下是一个无限循环,在检查了很长时间可能出错的地方之后,我认为我必须使用IMUL
,因为
但是现在还是不行。然后我再次查看手册,发现< code>mul bl
实际上将结果存储在< code>ax中。因此,我在< code>ax中有一个有符号的结果,而我希望在< code>al中有一个无符号的(有上溢/下溢)结果。
所以我的问题是:如何将ax
中的有符号结果转换为中的无符号结果?基本上与符号扩展相反。
注意:我在这里也包括了我的思维过程,因为我很可能正在做与预期不符的事情,因此到目前为止我找不到答案。
这是我在一个例子中的观点:如果乘法结果为负数,则表示你不为负数;如果结果为负值,则表示不为负值(我正在我的一个编译器中运行此代码):
mov bl, -5 ;◄■■ NEGATIVE NUMBER.
mov al, 10
imul bl ;◄■■ AX = -50 (0xFFCE).
cmp ax, 0
jl negative ;◄■■ IF AX < 0 JUMP TO NEGATIVE.
jmp continue ;◄■■ IF AX >= 0 SKIP NEGATIVE.
negative:
neg ax ;◄■■ AX => POSITIVE (0xFFCE => 0x32).
continue:
我无法正确理解评论中的问题和后续内容。如果这根本不是答案,请告诉我。
我也发现这个答案可能是@Jose的克隆,所以我正在考虑删除它,特别是如果我证明我误解了这个问题。
通过imul bl
,我们可以:
AL
(但结果是符号扩展为AX
)。AL
。在后一种情况下,你必须选择做什么。< br >一般来说,您必须将结果缩放回8位,这可以简单到求解比例2 < sup > 16 :2 < sup > 8 = AX:AL for AL,也可以更复杂(包括根本不是缩放或任何线性运算)。
在前一种情况下,我们需要计算结果的绝对值。
由于案例1假设结果符合AL
,寄存器AH
要么全零,要么全一,匹配AL
的符号位。
imul bl ;Original code
xor al, ah ;NOT AL iif the result is negative
sub al, ah ;AL = AL - (-1) = AL + 1 iif the result is negative
这利用了众所周知的身份,以两个互补的形式,neg(x)=not(x)1。
本文向大家介绍Intel x86 Assembly& Microarchitecture 16位寄存器,包括了Intel x86 Assembly& Microarchitecture 16位寄存器的使用技巧和注意事项,需要的朋友参考一下 示例 当英特尔定义最初的8086时,它是一个具有20位地址总线的16位处理器(请参阅下文)。他们定义了8个通用16位寄存器-但为某些指令赋予了它们特定的作用:
基本上指令有8->16、8->32、8->64、16->32和16->64。 32->64的转换在哪里?我必须使用签名版本吗? 如果是的话,您如何使用完整的64位来表示无符号整数?
本文向大家介绍Intel x86 Assembly& Microarchitecture 8位寄存器,包括了Intel x86 Assembly& Microarchitecture 8位寄存器的使用技巧和注意事项,需要的朋友参考一下 示例 前四个16位寄存器可以将其高低字节和低半字节直接作为自己的寄存器进行访问: AH和AL是AX寄存器的上半部分和下半部分。 BH和BL是BX寄存器的上半部分和下
本文向大家介绍verilog 移位寄存器,包括了verilog 移位寄存器的使用技巧和注意事项,需要的朋友参考一下 示例 具有异步复位功能的N位深移位寄存器。
我可以使用MOV指令将存储在内存中的数据项移动到我选择的通用寄存器中。 现在,不要向我开枪,但以下是如何实现的:
本文向大家介绍Intel x86 Assembly& Microarchitecture 32位寄存器,包括了Intel x86 Assembly& Microarchitecture 32位寄存器的使用技巧和注意事项,需要的朋友参考一下 示例 英特尔生产80386时,他们从16位处理器升级到了32位处理器。32位处理意味着两件事:要处理的数据都是32位,而要访问的内存地址是32位。为此,他们仍然