汇编指令操作数

Posted

技术标签:

【中文标题】汇编指令操作数【英文标题】:Assembly instruction operand 【发布时间】:2018-01-07 01:47:49 【问题描述】:

movq 40(%rdi), %rax 中的40 是什么意思?

我看到该值(在gcc 自动生成的其他指令中)始终是 8 的正倍数(即 8、16、24、32...)

它也总是被()包围

我也知道()是地址。

但是示例中的40 是什么意思呢? 当我尝试更改它时,它甚至允许非 8 的倍数(例如 2、3、7、-3、-28)并且编译良好。


通过将 40 更改为其他值的一些示例值:

movq    $1, (%rdi)
movq    0(%rdi), %rax

%rax: 2

movq    $1, (%rdi)
movq    1(%rdi), %rax

%rax: 72057594037927937

movq    $1, (%rdi)
movq    2(%rdi), %rax

%rax: 281474976710657

movq    $1, (%rdi)
movq    8(%rdi), %rax

%rax: 2

movq    $1, (%rdi)
movq    16(%rdi), %rax

%rax: 4

movq    $1, (%rdi)
movq    24(%rdi), %rax

%rax: 140730710821713

movq    $1, (%rdi)
movq    32(%rdi), %rax

%rax: 2761649059213359105

【问题讨论】:

movq 32(%rdi), %rax 将 32 添加到 %rdi 的内容中,并将其用作要移动的数据的地址。这是一个偏移量。这应该在任何程序集参考中进行描述。你读过文档吗?查找 x64 的“寻址模式”。 我不确定我是否理解。 movq $1, %rdi 然后 movq 32(%rdi), %rax 在运行时导致 seg 错误 确实如此,因为它尝试使用32+1=33 作为地址,而这通常是无效的。 不允许您的应用程序访问系统上的内存位置 33。所以你得到一个分段错误。应用程序不能任意访问它们想要访问的任何内存位置。 等等,你是不是没有看书/教程,只是看编译器输出来猜测程序集的作用?这条路将比您想象的要曲折得多,汇编语言更像是“硬件工程师所做的”,而不是“它在编程语言中的外观和意义”,因此,如果不阅读适当的书籍和文档,您的机会为零破译一些指令行为,例如mul ebxdiv ebx 是完全不可猜测的(但人们会尝试,然后他们会像每周左右一样发布新的 SO 问题)。 【参考方案1】:

40(%rdi) 在 AT&T 语法中是 [rdi + 40] 在 NASM 语法中。它是一个有效地址为 40 + RDI 的内存操作数。 0(%rdi)(%rdi) 是一回事:没有位移。见Referencing the contents of a memory location. (x86 addressing modes)。

您的第一个示例将一个 8 字节的 1 存储到 (%rdi),然后从同一地址重新加载。但是你声称你得到了2,所以你在那里做错了。

您的另一个示例是存储然后从部分重叠的位置(如rdi+2)或不重叠的位置(如rdi+16)加载。在后一种情况下,加载结果完全不依赖于 store。

【讨论】:

以上是关于汇编指令操作数的主要内容,如果未能解决你的问题,请参考以下文章

汇编指令,INC指令的操作数都可以是啥

汇编语言指令大全,要详细的 !!!!

汇编neg指令?

汇编指令机器码说明

16位汇编第六讲汇编指令详解第二讲

汇编语言--高级汇编技术