Jam*_*ark 6 x86 assembly multiplying
我试图在汇编中进行简单的乘法操作,但由于某种原因,我没有看到寄存器在标记MUL功能时发生变化.
mov bx, 5
mov cx, 10
mul cx
Run Code Online (Sandbox Code Playgroud)
Cod*_*ray 29
这些被称为指令,和他们指定的操作要由处理器来执行.mov对于mov e来说mul是一个助记符,而对于mul tiply来说则是一个助记符.其他常见的指令包括add,sub和div.我相信你可以弄清楚这些指定的操作!
大多数指令都有两个参数.在技术术语中,这些术语通常称为操作数.第一个(左侧)是目的地,第二个(右侧)是源.因此,在这种情况下mov bx, 5,这会将文字值移动5到目标寄存器中bx.当然,这些参数的顺序很重要,因为您无法将寄存器的内容移动bx到字面值5!
该mul指令有点奇怪,因为它的一些操作数是隐含的.也就是说,它们没有明确指定为参数.对于该mul指令,目标操作数被硬编码为ax寄存器.源操作数是您作为参数传递的操作数:它可以是寄存器或内存位置.
因此,您可以想象这mul cx意味着mul ax, cx,但您不会这样写,因为ax目标寄存器是隐式的.
现在,mul指令命令处理器将目标操作数乘以源操作数,并将结果存储在目标中.在代码中,您可以想象mul cx会转化为ax = ax * cx.现在你应该看到问题所在:你还没有初始化ax寄存器的内容,所以你将cx剩下的垃圾乘以10(这是你放入的值)ax.因此,结果毫无意义!
如果你实际上想要做5*10,那么你只需要更改代码中的一个字符:
mov ax, 5 ; ax = 5
mov cx, 10 ; cx = 10
mul cx ; ax = ax * cx
Run Code Online (Sandbox Code Playgroud)
结果将存储在ax隐式目标寄存器中.从技术上讲,结果将存储在dx:ax.这是一个寄存器对,意味着结果的高部分将被存储dx,而结果的低部分将被存储ax.为什么这个额外的并发症?因为乘以两个16位值可能会导致值大于16位!将结果返回到一对 16位寄存器允许mul指令返回32位结果.但是,当你刚刚学习时,你不必担心这一点.您可以忽略溢出的可能性,并从中提取结果的低部分ax.
虽然我确信这只是一个玩具示例,但实际上没有理由编写将两个常量相乘的代码.这可以在构建时完成,使用计算器并对值进行硬编码,或者象征性地写出常量的乘法并让汇编器进行计算.就是这样mov ax, 50.但就像我说的那样,我相信你已经知道了!
如果所有其他方法都失败了,请查阅文档以获取给您带来麻烦的说明.你几乎总能通过谷歌搜索指令的名称和"x86"在线找到它.例如,mul可以在此处找到文档以及其他几个站点.这些信息可能有点复杂,但通过一些努力,您应该能够提取所需的信息.您还可以在x86标签wiki中找到许多其他重要信息和链接.
但由于某种原因,我没有看到标记MUL功能时寄存器发生变化.
我还应该指出,如果您使用调试器来逐步执行代码,则当前标记/突出显示的行是即将执行的行.它尚未执行,因此它对寄存器,内存等的影响尚不可见.您必须跳过指令,以便标记/突出显示在下一行,然后您将看到前一个(刚刚执行的)指令的效果.
如果你理解了我上面的解释,在一条mul指令之后,你应该看到ax和dx寄存器的内容发生了变化.如果调试器显示其中任何一个,您还将看到标志和指令指针的变化.别的什么都不应该改变!(英特尔的说明参考手册未列出对机器架构状态的任何其他影响.)
该mul指令有 2 个操作数:一个是指定的,另一个是隐式的。
当你写的时候,mul cx它的意思是这样的:ax = ax * cx。
实际上,这意味着dx:ax = ax * cx- 完整 32 位产品的高半部分始终写入dx. dx对于结果“适合”的小型产品,该值为零ax。如果您只想要结果的低 16 位,您可以将其视为破坏dx1。
你的问题的答案,如果你真的想将 5 乘以 10,你可以这样做:
mov ax, 5 ; ax = 5
mov cx, 10 ; cx = 10
mul cx ; dx:ax = ax * cx
; So ax = ax * cx
; and dx=0 because the product happens to be small.
Run Code Online (Sandbox Code Playgroud)
脚注 1:186 允许imul dst, src, constantlike imul ax, cx, 5,允许任何寄存器而不隐式使用 AX 或 DX。
386 允许imul reg,reg在没有隐式寄存器的情况下进行非加宽乘法。
https://www.felixcloutier.com/x86/imul涵盖了这两种形式。
当然,如果您可以使用 386 个功能,您可以使用允许缩放索引(即内置移位计数)的 32 位寻址模式lea来imul代替乘以 3、5 或 9。
mov ecx, 10
lea ax, [ecx + ecx*4]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50628 次 |
| 最近记录: |