- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
为了加深对“(*p)++”是如何工作的印象,我写了一些测试代码如下:
int main()
{
int a = 3;
int *p = &a;
int b = (*p)++;
int *q = p++;
int c = a++;
int d = c++;
printf("a = %d, b = %d, c = %d, d = %d, p = %#x, q = %#x\n",a, b, c, d, p, q);
}
输出是:a = 5, b = 3, c = 5, d = 4, p = 0xc6dc3490, q = 0xc6dc348c
但我的问题是关于程序集(代码是按顺序排列的,而不是断断续续的):
main:
push rbp
mov rbp, rsp
sub rsp, 48
;int a = 3 :
mov DWORD PTR [rbp-36], 3
;int *p = &a :
lea rax, [rbp-36]
mov QWORD PTR [rbp-8], rax
;int b = (*p)++ :
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
lea ecx, [rax+1] ;Flag1
mov rdx, QWORD PTR [rbp-8]
mov DWORD PTR [rdx], ecx
mov DWORD PTR [rbp-12], eax
;int *q = p++ :
mov rax, QWORD PTR [rbp-8] ;Flag2
lea rdx, [rax+4] ;Flag3
mov QWORD PTR [rbp-8], rdx
mov QWORD PTR [rbp-24], rax
;int c = a++;
mov eax, DWORD PTR [rbp-36]
lea edx, [rax+1] ;Flag4
mov DWORD PTR [rbp-36], edx
mov DWORD PTR [rbp-28], eax
;int d = c++;
mov eax, DWORD PTR [rbp-28]
lea edx, [rax+1] ;Flag5
mov DWORD PTR [rbp-28], edx
mov DWORD PTR [rbp-32], eax
... ... (ignore some)
请注意让我感到困惑的“Flagx”行。
从上面我们知道
当指针:int *q = p++ :
lea rdx, [rax+4] ;Flag3
在这里,“lea”似乎读取了“rax”和 +4 中存储的地址值。然后传递给“rdx”。
while: int c = a++ 或 int d = c++ :
lea edx, [rax+1] ;Flag4/Flag5
这里'lea'好像读取了'rax'中addr值存储的内容(这里是3),+1,得出4,传给'edx'。
但是!关键是这两个语句中的“rax”是同一个。他们都来自
mov rax, QWORD PTR [rbp-8] ;Flag2
正如我们所见,它们(Flag3 和 Flag4/Flag5)看起来非常相似,但基于相同的“rax”,它们的工作方式却截然不同,这是怎么回事? “lea”指令能否区分“rdx”和“edx/ecx”并得出不同的结果?
非常感谢。
最佳答案
Here, 'lea' seems to read the content of the addr value store in 'rax' (which is 3 here), and +1, come to 4 and pass to 'edx'.
不,你错了。 lea edx, [rax+1]
不会改变 rax
。在评估 lea
指令之前,rax
已经是 3
。
But! the point is that 'rax' in these two statments are the same one. They're all from
mov rax, QWORD PTR [rbp-8]
不,你错了。 rax
由 mov eax, DWORD PTR [rbp-36]
设置。
通用寄存器的不同部分可以使用不同的名称来引用。
64 32 16 8 0
| | | | |
v v v v v
+----+----+----+----+----+----+----+----+
| | | | | | | | |
+----+----+----+----+----+----+----+----+
|<------------------------------------->| rax
|<----------------->| eax
|<------->| ax
|<-->| ah
|<-->| al
这意味着当您写入 eax
时,您也在写入 rax
的下半部分(并且上半部分归零)。
所以,
; rax eax rdx edx
; q = p++ ; +----+----+----+----+ +----+----+----+----+
A1 mov rax, QWORD PTR [rbp-8] ; | p | | ??? |
A2 lea rdx, [rax+4] ; | p | | p+4 |
A3 mov QWORD PTR [rbp-8], rdx ; | p | | p+4 |
A4 mov QWORD PTR [rbp-24], rax ; | p | | p+4 |
; c = a++ ; | p | | p+4 |
B1 mov eax, DWORD PTR [rbp-40] ; | 0 | a | | p+4 |
B2 lea edx, [rax+1] ; | 0 | a | | 0 | a+1 |
B3 mov DWORD PTR [rbp-40], edx ; | 0 | a | | 0 | a+1 |
B4 mov DWORD PTR [rbp-28], eax ; | 0 | a | | 0 | a+1 |
; +----+----+----+----+ +----+----+----+----+
关于c - int *q = p++ 和 int c = a++ 的汇编 lea 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44773658/
例子一 function first(a, b) { return a + b; } function second() { return Math.floor(Math.sqrt(a
我想证明或证伪forall (P Q : Prop), (P -> Q) -> (Q -> P) -> P = Q.在柯克。这是我的方法。 Inductive True2 : Prop := | O
程序提取数字,我希望它继续循环,直到用户键入“Q”/“q”键。例如,当用户按下“O”键时,程序应打印他们输入的数字的个位数,对于用户输入的任何 3 位数字,依此类推。当我现在运行代码时,没有输出,但也
我收到以下代码的警告,我不明白为什么。 类似于这个问题:Unhandled rejection reasons (should be empty) 但是…… 我很确定我正在处理所有错误,那么为什么会出
我正在使用 Express 构建一个博客站点,并且是第一次使用 Q,我希望能够利用资深 Q 用户的知识。 我向我的数据库发出一个请求以加载帖子数据,另一个请求命中 Instagram API(除非它已
我刚刚找到有关 apache solr 的信息,并且在我成功安装了带有 Tomcat 的 apache Solr 之后。然后我开始使用 Apache Solr 进行搜索。 但我对 Apache Sol
我在 Stack Overflow post 上看到了下图 但是,我对“p OR q”、“p AND q”的结果感到困惑,其中“p”等于“false”,“q”等于“unknown”。 在图中,“p O
有人向我提出了这个问题。 n = 77 n = p*q p and q is a prime number 用蛮力找到p和q。 到目前为止我的代码: public class If { pub
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 4 年前。 Improve
我注意到如果 .then()回调由于任何错误(例如对 undefined variable 的操作)而失败,并且没有 .catch()相关联,该错误将被静默忽略。 这在开发过程中很不舒服。 例如,此代
以下示例打印“SAME”: if (q/\\a/ eq q/\a/) { print "SAME\n"; } else { print "DIFFERENT\n"; } 我理解这与 d
我画了 qq 图多元回归,得到了下面的图。谁能告诉我为什么红线下面有两个点?这些点对我的模型有影响吗? 我使用下面的代码来绘制图表。 from sklearn.linear_model import
我确定 int q[6][4] 中的 q 的类型为 (**q)[4],即, 指向大小为 4 的整数数组的指针。但是我的书(我发现它很可疑!!)说函数定义中的 int q[][4] 部分 void fo
我试图用 tatics [intros]、[apply]、[assumption]、[destruct]、[left]、[right]、[split] 来证明这个引理,但失败了。谁能教教我怎么证明?
使用 q.all 时,我的数组中的立即函数似乎没有执行。每个函数都应该创建一个已解决的 promise ,将其打印到控制台,然后返回它。我没有看到控制台输出,但 Q.all 似乎很满意,并用 2 个空
我想在 OpenAI 的 Bipedal Walker v2 中实现 Q 学习,但在寻找教程后,它们似乎总是有限环境,这使得 Q 矩阵和奖励矩阵易于初始化。 例如:http://mnemstudio.
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我正在创建一个基于 AngularJS、Breeze 和 RequireJS 的单页应用程序。在使用 requirejs 设置 AMD 以使用 Angular 和 Breeze 时,我遇到了 Bree
这个问题在这里已经有了答案: Difference between defer().promise and Promise (1 个回答) 关闭 6 年前。 在 Angular 中,以下代码片段似乎
我写了一个 tcp 服务器和一个 tcp 客户端,客户端只向服务器发送数据并打印它写入了多少字节,服务器只接受连接,然后我使用 netstat 显示套接字的 Recv-Q 和 Send-问,我发现 R
我是一名优秀的程序员,十分优秀!