这些被称为指示,并且他们指定运营由处理器执行。mov
是一个助记符move,同时mul
是一个助记符mul尖利的。其他常见指令包括add
, sub
, and div
。我相信你能弄清楚这些具体是什么操作!
大多数指令有两个参数。在技术术语中,这些通常被称为operands。第一个(左边)是目的地,第二个(右边)是source。所以,在这种情况下mov bx, 5
,这会移动文字值5
进入目标寄存器bx
。当然,这些参数的顺序很重要,因为您无法移动寄存器的内容bx
转化为字面值5
!
The mul
指令有点奇怪,因为它的一些操作数是隐式的。也就是说,它们没有明确指定为参数。为了mul
指令,目标操作数被硬编码为ax
登记。源操作数是作为参数传递的操作数:它可以是寄存器或内存位置。
因此,你可以想象mul cx
means mul ax, cx
,但你不会那样写,因为ax
目标寄存器是隐式的。
Now, a mul
指令命令处理器将目标操作数与源操作数相乘,并将结果存储到目标中。在代码中,你可以想象mul cx
会翻译成ax = ax * cx
。现在你应该看到问题:你还没有初始化ax
寄存器,所以你乘以 10 (这是你放入的值cx
)通过留在其中的任何垃圾ax
。这样一来,结果就毫无意义了!
如果您实际上想要执行 5 * 10,那么您只需更改代码中的一个字符:
mov ax, 5 ; ax = 5
mov cx, 10 ; cx = 10
mul cx ; ax = ax * cx ; actually dx:ax = ax * cx
结果将存储在ax
,这是隐式目标寄存器。
嗯,从技术上讲,结果将存储在dx:ax
。这是一个寄存器对,并且意味着结果的高部分将存储在dx
,而结果的低部分将存储在ax
。为什么会出现这种额外的并发症?因为两个 16 位值相乘可能会得到一个大于 16 位的值!返回完整的乘法结果pair16位寄存器允许mul
返回 32 位结果的指令。不过,当你刚刚学习时,你不需要担心这个。您可以忽略溢出的可能性,并从中提取结果的低部分ax
。 (但请记住 16 位mul
覆盖dx
不管你想要与否。在 386 及更高版本上您可以使用imul ax, cx
真正做ax *= cx
不浪费时间写作dx
.)
虽然我确信这只是一个玩具示例,但确实没有理由写code将两个常数相乘。这可以在构建时完成,可以使用计算器并对值进行硬编码,或者以符号方式写出常量的乘法并让汇编器进行计算。那是,mov ax, 50
。或者让你的汇编器为你做这件事mov ax, 5 * 10
。但就像我说的,我相信你已经知道了!
如果所有其他方法都失败,请参阅文档以查找给您带来麻烦的说明。您几乎总是可以通过谷歌搜索指令名称和“x86”来在线找到它。例如,mul
可以找到文档here http://www.felixcloutier.com/x86/MUL.html,以及其他几个网站。这些信息可能有点复杂,但只要付出一些努力,您应该能够提取所需的信息。您还可以在以下位置找到许多其他重要信息和链接x86 /questions/tagged/x86 tag wiki https://stackoverflow.com/tags/x86/info.
但由于某种原因,当 MUL 函数被标记时,我没有看到寄存器发生变化。
我还应该指出,如果您使用调试器单步调试代码,则当前标记/突出显示的行是about执行。它还没有执行,所以它对寄存器、内存等的影响还不可见。您必须跳过指令,以便标记/突出显示在next行,然后您将看到上一条(刚刚执行的)指令的效果。
如果你理解了我上面的解释,经过一段时间mul
说明,您应该看到的内容ax
and dx
寄存器发生变化。如果您的调试器显示其中任何一个,您还将看到标志和指令指针发生变化。其他什么都不应该改变! (Intel的指令参考手册条目为mul https://www.felixcloutier.com/x86/mul没有列出对机器架构状态的任何其他影响。)