【问题标题】:Weird results with movzwl, %ax and negative valuesmovzwl、%ax 和负值的奇怪结果
【发布时间】:2011-09-06 06:03:27
【问题描述】:

好的,所以我正在处理以下 sn-p 代码:

push   %ebp
mov    %esp,%ebp   
push   %ebx
mov    0x8(%ebp),%eax 
movzwl %ax,%edx

因此,在处理正值时,它的行为符合预期。复制到 %edx 的值是 %eax(或 %ax)的尾随 16 位。

但是,如果你输入一个负数,一切都会变得很奇怪,而且它的行为似乎不像预期的那样。

例如,如果 %eax 的值为 -67043552,则复制到 %edx 中的值为 65312。

我对组装还很陌生,如果这显然是我的误解,我很抱歉。任何帮助将不胜感激。

【问题讨论】:

  • movswl 在您想要对 2 的补码有符号值进行符号扩展而不是对二进制无符号值进行零扩展时可用。 (另见x86 tag wiki
  • 另外,如果您将数字打印为十六进制,那么所发生的事情会更容易混淆/更明显。
  • 另外,除非你真的需要%eax 中的完整值,否则你应该直接movzwl 0x8(%ebp), %edx 而不是浪费一条指令单独执行。英特尔 CPU 可以将 movzx / movsx 仅作为加载微指令处理,无需 ALU。

标签: assembly x86 sign-extension zero-extension


【解决方案1】:

请记住,movzwl 仅将 %ax 中的位复制到 %edx 中,用零填充 %edx 的高 16 位。

所以%edx 总是以小于或等于 65535 的正数结束。

详细说明:十六进制的-67043552fc00ff20。所以如果它在%eax 中,那么%ax 包含ff20。如果您将其移动到具有零扩展名的%edx,则%edx 将获得0000ff20。那是 65312。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 2012-12-16
    相关资源
    最近更新 更多