请验证 AT&T 装配线的含义

Posted

技术标签:

【中文标题】请验证 AT&T 装配线的含义【英文标题】:Please verify meaning of AT&T Assembly line 【发布时间】:2013-02-19 05:17:38 【问题描述】:

这条线对我来说不是很清楚(我对大会很陌生):

movsbl 0xffffffff(%edx,%ebx,1),%eax

我了解mov,但movsbl 对我来说是新的。在一个使用foo 而不是0xffffffff(%edx,%ebx,1) 的更简单的示例中,我理解它是这样的(完全不确定这是否正确,只是搜索了一个相关主题):

eax = foo&0x800000ff;

我从未有过一行汇编引用-1 (0xffffffff),放入%eax 的信息究竟来自哪里?是否存储在:

[%edx + %ebx -1]

【问题讨论】:

x86 instruction meaning 的可能重复项 博佩尔松,怎么复制的? 【参考方案1】:
movsbl <%x, %y, 1>, %z

说,从第一个操作数 (x) 寻址的内存位置读取一个字节,将该字节扩展为 32 位,并将结果存储在寄存器 (z) 中。

是x和y的值相加形成的内存地址; 1 是应用于 y 的乘数。

【讨论】:

你能解释一下当一个字节扩展到 32 位时会发生什么吗?它是否用零填充 3 个最重要的字节?我从不同的解释中看到它“符号扩展”。我试图通过写 0x800000ff 来证明,是正确的还是错误的? 扩展 = 从字节扩展到长字。在 Intel 语法中,该指令的助记符是 MOVSX。当需要将 int8_t 类型的变量转换为 int 时,C 编译器可能会使用此指令,这会在算术和一些其他操作(例如整数提升)中自动发生。该指令写入目标寄存器的所有 32 位(或其他),它避免了仅写入寄存器的低 8 位可能导致的性能损失。 我的意思是放入 3 个最重要的字节。我假设最低有效字节是复制的字节,但其他字节呢?无论如何,它们都是零吗? 是的,寄存器是用零填充的。 movsx 的前 24 位最终等于源字节的最高有效位,因此是 sign 扩展名。 movzx 用 0 填充这 24 位,因此扩展名为 zero【参考方案2】:

如果你用 C 来写,这行代码类似于:

#include <stdlib.h>

int loadByte(char *base, size_t index)

    return (int)base[index - 1];

编译它(在 UN*X 上,对于 64 位 x86)会产生以下目标代码:

段.text的反汇编:

0000000000000000 :
   0: 0f 为 44 37 ff movsbl 0xffffffffffffffff(%rdi,%rsi,1),%eax
   5:c3 retq

如前所述,movsb 表示 移动(加载)一个字节,将其符号扩展为 ...(因此有 movsbwmovsblmovsbq 用于转换为word / short, long / int and quad / long long)。

你的程序集是32位的(因为用于寻址的寄存器都是32位的),其他的意思是一样的。

【讨论】:

以上是关于请验证 AT&T 装配线的含义的主要内容,如果未能解决你的问题,请参考以下文章

装配内联 AT&T 类型不匹配

JL 在 at&t 语法中是啥意思?

PL/SQL 中的双“at”符号含义

请解释下面delphi代码每句的含义

Rust:split_at_mut(即 join_mut)有相反的含义吗?

make/makefile中的加号+,减号-和at号@的含义