你怎么能告诉计算机它正在添加而没有 addl 在程序集中
How can you tell a computer it is adding without addl in Assembly
我对 Assembly 略知一二。那么我先介绍一下代码,再说说我的思路。
#This is the Assembly version.
pushq %rbp
movq %rsp, %rbp
movl , -4(%rbp)
movl , -8(%rbp)
movl , %eax
popq %rbp
ret
#This is the C version.
int twothree() {
int a = 2;
int b = 3;
return 2 + 3;
}
好吧,首先让我吃惊的是,我们没有将变量a和b用作a + b。所以它们是不必要的,我们直接对整数求和。然而,如果计算机能够理解这一点,我想那将是非常可怕的。所以,我的问题是:这段汇编代码在没有任何 addl 或类似命令的情况下是如何工作的?我们直接将立即数(或常量)整数5移动到eax registrar.
另外,快速提问。那么最后两行之后的 a 和 b 变量会发生什么变化呢?他们在堆栈中的位置(或者我们可以称他们用作内存位置的 'registrars')现在是空闲的,因为我们使用 malloc + free。这是真的还是至少是合乎逻辑的? popq %rbp 我猜是关闭堆栈的命令。
正如我所说,我不是汇编方面的专家。所以这些想法大部分都只是在想。谢谢!
编译器发现您要将两个数字相加 2 + 3
。编译器计算出 2+3=5 并将 5 放入汇编代码中。这叫做“不断折叠”。
我猜你在编译器中关闭了优化,因为它没有删除无用的变量 a
和 b
。但是常量折叠对编译器来说非常容易(不像其他类型的优化)并且很有用,所以即使你没有打开优化,编译器似乎也在做。
如您所见,汇编代码不会 添加 2 和 3,因为没有 addl
或类似的命令。它只是 return 5;
汇编编程中没有命令或代码。相反,汇编代码(不可数)包含指令和指令。
您在哪里看到 malloc
或 free
的用法?这些是用于管理 动态内存 的函数,这不是您的程序使用的东西。如果使用了这些函数中的任何一个,您将在某处的代码中有一个 call malloc
或 call free
指令。变量a
和b
都在自动存储,即栈上
现在您的代码中发生的情况是,编译器已执行 常量折叠 以发出代码,就像您编写的那样
#This is the C version.
int twothree() {
int a = 2;
int b = 3;
return 5;
}
无论优化标志如何,编译器都会执行此操作。所以确实,在 运行 时间没有发生任何添加。它已经在编译时的常量折叠期间执行了。
Also, quick question. So what happens to the a and b variables after last two lines? Their position in stack (or maybe we can call the 'registrars' they used as a memory place) are free now as we use malloc + free. Is it true or at least logical? popq %rbp is the command for closing the stack I guess.
变量存储在红色区域, 堆栈指针下方的 128 字节内存区域,可免费用作暂存区,无需显式分配。因此,不需要代码为它们分配或释放存储空间。
现在,没有“关闭堆栈”这样的东西了。堆栈是内存中的一个区域。 栈指针rsp
指向栈顶,而基指针rbp
指向栈底当前堆栈帧。你会经常看到像
这样的代码
push %rbp
mov %rsp, %rbp
...
pop %rbp
在函数的开始和结束处建立和拆除堆栈帧。阅读组装教程了解更多详情。
我对 Assembly 略知一二。那么我先介绍一下代码,再说说我的思路。
#This is the Assembly version.
pushq %rbp
movq %rsp, %rbp
movl , -4(%rbp)
movl , -8(%rbp)
movl , %eax
popq %rbp
ret
#This is the C version.
int twothree() {
int a = 2;
int b = 3;
return 2 + 3;
}
好吧,首先让我吃惊的是,我们没有将变量a和b用作a + b。所以它们是不必要的,我们直接对整数求和。然而,如果计算机能够理解这一点,我想那将是非常可怕的。所以,我的问题是:这段汇编代码在没有任何 addl 或类似命令的情况下是如何工作的?我们直接将立即数(或常量)整数5移动到eax registrar.
另外,快速提问。那么最后两行之后的 a 和 b 变量会发生什么变化呢?他们在堆栈中的位置(或者我们可以称他们用作内存位置的 'registrars')现在是空闲的,因为我们使用 malloc + free。这是真的还是至少是合乎逻辑的? popq %rbp 我猜是关闭堆栈的命令。
正如我所说,我不是汇编方面的专家。所以这些想法大部分都只是在想。谢谢!
编译器发现您要将两个数字相加 2 + 3
。编译器计算出 2+3=5 并将 5 放入汇编代码中。这叫做“不断折叠”。
我猜你在编译器中关闭了优化,因为它没有删除无用的变量 a
和 b
。但是常量折叠对编译器来说非常容易(不像其他类型的优化)并且很有用,所以即使你没有打开优化,编译器似乎也在做。
如您所见,汇编代码不会 添加 2 和 3,因为没有 addl
或类似的命令。它只是 return 5;
汇编编程中没有命令或代码。相反,汇编代码(不可数)包含指令和指令。
您在哪里看到 malloc
或 free
的用法?这些是用于管理 动态内存 的函数,这不是您的程序使用的东西。如果使用了这些函数中的任何一个,您将在某处的代码中有一个 call malloc
或 call free
指令。变量a
和b
都在自动存储,即栈上
现在您的代码中发生的情况是,编译器已执行 常量折叠 以发出代码,就像您编写的那样
#This is the C version.
int twothree() {
int a = 2;
int b = 3;
return 5;
}
无论优化标志如何,编译器都会执行此操作。所以确实,在 运行 时间没有发生任何添加。它已经在编译时的常量折叠期间执行了。
Also, quick question. So what happens to the a and b variables after last two lines? Their position in stack (or maybe we can call the 'registrars' they used as a memory place) are free now as we use malloc + free. Is it true or at least logical? popq %rbp is the command for closing the stack I guess.
变量存储在红色区域, 堆栈指针下方的 128 字节内存区域,可免费用作暂存区,无需显式分配。因此,不需要代码为它们分配或释放存储空间。
现在,没有“关闭堆栈”这样的东西了。堆栈是内存中的一个区域。 栈指针rsp
指向栈顶,而基指针rbp
指向栈底当前堆栈帧。你会经常看到像
push %rbp
mov %rsp, %rbp
...
pop %rbp
在函数的开始和结束处建立和拆除堆栈帧。阅读组装教程了解更多详情。