我对组装有点了解.让我先介绍一下代码,然后解释一下我的思维方式.

#This is the Assembly version.
pushq   %rbp
movq    %rsp, %rbp
movl    $2, -4(%rbp)
movl    $3, -8(%rbp)
movl    $5, %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寄存器.

还有,快速提问.那么,在最后两行之后,a和b变量会发生什么变化呢?当我们使用malloc+free时,它们在堆栈中的位置(或者我们可以称之为它们用作存储位置的"注册器")现在是空闲的.这是真的还是至少合乎逻辑?popq%rbp是关闭堆栈的命令.

我不是我说过的组装专家.所以这些 idea 大多只是在思考.谢谢

推荐答案

汇编编程中没有commandscodes.相反,assembly code(不可数)包含instructionsdirectives.

你认为mallocfree的用法在哪里?这些函数用于管理dynamic memory,而您的程序不使用这些函数.如果使用这两个函数中的任何一个,代码中的某个地方就会有call malloccall free指令.变量ab都在automatic storage中,即在堆栈上.

现在,在你的代码中发生的是,编译器已经执行了constant folding次,以发出代码,就像你写的一样

#This is the C version.
int twothree() {
    int a = 2;
    int b = 3;

    return 5;
}

这是编译器在不考虑优化标志的情况下所做的事情.因此,实际上,在运行时不会发生任何添加.它已经在编译时的常量折叠期间执行.

还有,快速提问.那么,在最后两行之后,a和b变量会发生什么变化呢?当我们使用malloc+free时,它们在堆栈中的位置(或者我们可以称之为它们用作存储位置的"注册器")现在是空闲的.这是真的还是至少合乎逻辑?popq%rbp是关闭堆栈的命令.

存储在red zone,字节内存中的变量在堆栈指针下方有一个128字节的内存区域,可以作为临时数据使用,无需显式分配.因此,不需要代码为它们分配或释放存储.

现在,没有"关闭堆栈"这样的事情堆栈是内存中的一个区域.堆栈的顶部由stack pointer rsp指向,而base pointer rbp指向当前堆栈帧的底部.你经常会看到这样的代码

push %rbp
mov %rsp, %rbp
...
pop %rbp

在函数的开始和结束处建立并分解堆栈框架.有关详细信息,请阅读组装教程.

C++相关问答推荐

想了解 struct 指针和空指针转换

来自stdarg.h的c中的va_args无法正常工作<>

在C中使用动态内存分配找到最小的负数

编译的时候g++通常会比GCC慢很多吗?

GCC引发不明确的诊断消息

减法运算结果的平方的最快方法?

这是一个合法的C Strdup函数吗?

为什么GCC在每次循环迭代时都会生成一个数组的mov&S使用[]访问数组?(-03,x86)

Rust FFI--如何用给出返回引用的迭代器包装C风格的迭代器?

如何在不使用其他数组或字符串的情况下交换字符串中的两个单词?

实现简单字典时C语言中的段错误

使用错误的命令执行程序

是否可以通过调用两个函数来初始化2D数组?示例:ARRAY[STARTING_ROWS()][STARTING_COLUMNS()]

ifdef __cplusplus中的整数文字单引号

用于计算位数和的递归C函数

计算时出现奇怪的计算错误;N Select K;在C中

即使客户端不发送数据,也会发生UNIX套接字读取

我的代码可以与一个编译器一起使用,但不能与其他编译器一起使用

根据输入/输出将 C 编译过程分为预处理、编译、汇编和链接步骤

如何转义包含指令中的字符?