我对32位x86 imul
操作码的一个语义感到困惑。这是一个例子:
mov eax, 0x0fffffff
mov ebx, 0x0fffffff
imul eax, ebx <---- eax??
似乎0x0fffffff * 0x0fffffff
等于0xffffffe0000001
,大于0xffffffff
,因此eax
应在0xe0000001
后分配给imul
}。
所以这是我的问题,高位(0x00ffffff
)在哪里? cpu
是否使用edx
来存储更高的位?或者它只是设置overflow
标志?
答案 0 :(得分:2)
x86代码wiki包含可用于查找各种指令信息的资源列表。例如,在http://www.felixcloutier.com/x86/上搜索IMUL会引导您http://www.felixcloutier.com/x86/IMUL.html。
所以它取决于你的汇编程序如何编译它,如果使用了两个操作数变量,那么结果被截断,如果使用单个操作数(IMUL ebx
),则结果在edx:eax
。< / p>
关于标志:可能是调试以确定,但是两个操作数版本,如果我正确读取它会在结果被截断时设置CF / OF,所以在你的情况下CF = 1,OF = 0? (unsigned trunc,signed not overflow)。
3小时后...... 在我看来,我实际上应该再次搜索一些不错的linux调试器,比如DOS时代Borland的“TD”,因为它可能很方便。
当然gdb总是存在,但我不能喜欢它(特别是因为它通常采用AT&amp; T语法,我个人不喜欢)。
所以我尝试了“ddd”(数据显示调试器),可直接在Ubuntu存储库中使用,但它看起来有点旧(是的,MOTIF,如果你知道,我的意思是,如果你从未听过MOTIF,那么你不是够老了)。这是基于gdb的......对于想要进入GNU路径的人来说,可能值得一提,但我进一步搜索了。
我最终下载并编译了edb-debugger。经过几次尝试,我得到它在我的旧ubuntu上编译,运行它...并且......那就是IT。只需点击几下偏好,“TD”感觉就在这里。
所以,我尝试了你的指令(必须首先从NASM示例中编译一些helloworld.asm以运行一些测试linux二进制文件,然后你可以直接在调试器中覆盖这些简短问题的指令)。
在IMUL eax,ebx
之后,对CPU状态的更改为:
eax = 0xe0000001
CF = 1, OF = 1, SF = 1, ZF = 0, PF = 0, AF = 0, ...
在IMUL ebx
之后,对CPU状态的更改为:
eax = 0xe0000001
edx = 0x00ffffff
CF = 1, OF = 1, SF = 1, ZF = 0, PF = 0, AF = 0, ...
(所以在这种情况下标志是相同的)。
我强烈建议你也要一些好的调试器,不要再问这些问题了。如果让一个调试器运行不符合我自己的兴趣,我就不愿意回答。