【发布时间】: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 ebx或div ebx是完全不可猜测的(但人们会尝试,然后他们会像每周左右一样发布新的 SO 问题)。