我将 C 代码翻译成 CPU 的说明是否正确?
is my translation C code to instructions for CPU correct?
对于此代码:
int main(void) {
int a = 1;
int b = 2;
int* pa = &a;
*pa = a + b;
printf("%d", a);
}
在编译时,编译器计算它需要多少 space。我们有 2 个整数和一个指针。所以是2*4 + 8 = 16
。然后它指定给定变量的内存相对于起始点地址的位置。
pa
在起点地址,长度为8字节。
b
位于起点地址 + 8 个字节,长度为 4 个字节。
a
位于起点地址 + 12 个字节,长度为 4 个字节。
然后去说明执行时间:
- 要求 OS 分配 16 个字节并提供 space 在内存中的地址。这将是起点地址。
- 将
1
的二进制表示放在a
的位置。
- 将
2
的二进制表示放在b
的位置。
- 将
a
的相对地址(起点地址+12字节)翻译成它的绝对位置,放在pa
的位置。
- 获取位置
a
的字节和位置 b
的字节,将它们相加,然后获取位置 pa
的字节。使用位置 pa
处的字节作为地址并将计算出的总和放在那里。
- 打印位于
a
位置的字节,首先将它们转换为十进制数。
- 释放内存并让 OS 知道程序已完成。
这是一个有效的翻译吗?
编辑:
让我们假设使用了一个超级简单的编译器(没有优化)。它只关心 C 代码的有效执行。
这几乎是一种翻译方式(a),尽管函数的局部变量通常分配在堆栈上而不是而不是向 OS 请求一些内存来存储它们。
当然,使用智能编译器,源代码中有足够的信息可以简单地将整个代码优化为:
int main(void) { putchar('3'); }
(a) ISO C 标准没有规定如何事情是如何在幕后完成的,只是他们以特定的方式表现.将 C 视为实现标准的虚拟机。 VM 是如何做的并不真正相关,而且除了行为之外当然没有以任何方式强制执行。
据我所知,是的,这是一个有效的翻译。不,它几乎 100% 肯定不是您的编译器将要生成的翻译。 C 标准有所谓的 as-if rule 这意味着编译器可以自由地生成 任何 程序,其副作用是 就好像 程序是为所谓的抽象 C 机器编译的,运行 在那里。
实际上,编译器可以生成以下程序:
- 将整数
'3'
放入用作函数调用第一个参数的寄存器中
- 致电
putchar
- 将用作 return 值的寄存器置零
- return 来自
main
函数
对于观察者来说,这个程序的副作用与你的程序的副作用是无法区分的:它从 main
和 0
打印 3
和 returns作为 return 值。
步骤1变量a
、b
和pa
将被分配到栈中。因此,没有向 OS 请求内存分配——您将只使用由进程本身控制的堆栈。也许它不会要求 16 个字节——4 个字节就足够了,因为您有效地使用了变量 a
。甚至那个是常量,所以 a
的实例可以替换为 1
.
第 4 步: 这一步可能会被编译器完全跳过,因为在下一步重新分配之前您不会使用 pa
的值。
第 6 步: 将两个参数(%d[=17=]
字符串和值 1
)压入堆栈并调用名为 printf
的函数.不知道它是否输出到终端 - 也许 stdout
正在重定向到文件?
最终无法确切知道源代码会产生哪些指令。取决于体系结构,操作 system/OS 版本,compiler/cc 版本,编译器标志...
对于此代码:
int main(void) {
int a = 1;
int b = 2;
int* pa = &a;
*pa = a + b;
printf("%d", a);
}
在编译时,编译器计算它需要多少 space。我们有 2 个整数和一个指针。所以是2*4 + 8 = 16
。然后它指定给定变量的内存相对于起始点地址的位置。
pa
在起点地址,长度为8字节。
b
位于起点地址 + 8 个字节,长度为 4 个字节。
a
位于起点地址 + 12 个字节,长度为 4 个字节。
然后去说明执行时间:
- 要求 OS 分配 16 个字节并提供 space 在内存中的地址。这将是起点地址。
- 将
1
的二进制表示放在a
的位置。 - 将
2
的二进制表示放在b
的位置。 - 将
a
的相对地址(起点地址+12字节)翻译成它的绝对位置,放在pa
的位置。 - 获取位置
a
的字节和位置b
的字节,将它们相加,然后获取位置pa
的字节。使用位置pa
处的字节作为地址并将计算出的总和放在那里。 - 打印位于
a
位置的字节,首先将它们转换为十进制数。 - 释放内存并让 OS 知道程序已完成。
这是一个有效的翻译吗?
编辑:
让我们假设使用了一个超级简单的编译器(没有优化)。它只关心 C 代码的有效执行。
这几乎是一种翻译方式(a),尽管函数的局部变量通常分配在堆栈上而不是而不是向 OS 请求一些内存来存储它们。
当然,使用智能编译器,源代码中有足够的信息可以简单地将整个代码优化为:
int main(void) { putchar('3'); }
(a) ISO C 标准没有规定如何事情是如何在幕后完成的,只是他们以特定的方式表现.将 C 视为实现标准的虚拟机。 VM 是如何做的并不真正相关,而且除了行为之外当然没有以任何方式强制执行。
据我所知,是的,这是一个有效的翻译。不,它几乎 100% 肯定不是您的编译器将要生成的翻译。 C 标准有所谓的 as-if rule 这意味着编译器可以自由地生成 任何 程序,其副作用是 就好像 程序是为所谓的抽象 C 机器编译的,运行 在那里。
实际上,编译器可以生成以下程序:
- 将整数
'3'
放入用作函数调用第一个参数的寄存器中 - 致电
putchar
- 将用作 return 值的寄存器置零
- return 来自
main
函数
对于观察者来说,这个程序的副作用与你的程序的副作用是无法区分的:它从 main
和 0
打印 3
和 returns作为 return 值。
步骤1变量a
、b
和pa
将被分配到栈中。因此,没有向 OS 请求内存分配——您将只使用由进程本身控制的堆栈。也许它不会要求 16 个字节——4 个字节就足够了,因为您有效地使用了变量 a
。甚至那个是常量,所以 a
的实例可以替换为 1
.
第 4 步: 这一步可能会被编译器完全跳过,因为在下一步重新分配之前您不会使用 pa
的值。
第 6 步: 将两个参数(%d[=17=]
字符串和值 1
)压入堆栈并调用名为 printf
的函数.不知道它是否输出到终端 - 也许 stdout
正在重定向到文件?
最终无法确切知道源代码会产生哪些指令。取决于体系结构,操作 system/OS 版本,compiler/cc 版本,编译器标志...