源代码可以直接转换为机器代码(100000)。那为什么我们需要将其转换为IR(Intermediate Representation)汇编语言呢?
如果我不能直接转换成机器语言,有什么优点和缺点?
我正在处理有关链接的文本,并希望与所述文本中的一些示例一起工作。
为了更好地理解调用gcc驱动程序时发生了什么,我正在考虑手工完成所有的老式编译;
cppcc1 as ld不幸的是,在我的 Mac 上,我似乎无法cc1直接引用(没有列出cc1in man)。我有哪些选择?
当我在断言测试运行期间遇到一个奇怪的问题时,我正在自学CSAPP并得到一个奇怪的结果.
我不知道该怎么开始这个问题,所以让我先得到代码(文件名在评论中可见):
// File: 2.30.c
// Author: iBug
int tadd_ok(int x, int y) {
if ((x ^ y) >> 31)
return 1; // A positive number and a negative integer always add without problem
if (x < 0)
return (x + y) < y;
if (x > 0)
return (x + y) > y;
// x == 0
return 1;
}
Run Code Online (Sandbox Code Playgroud)
// File: 2.30-test.c
// Author: iBug
#include <assert.h>
int tadd_ok(int x, int y);
int main() {
assert(sizeof(int) == 4); …Run Code Online (Sandbox Code Playgroud) 这是一个简单的C代码
#include <stdio.h>
int a = 5;
static int b = 20;
int main(){
int c = 30;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译为无需优化的组合:
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 13
.globl _main ## -- Begin function main
.p2align 4, 0x90
_main: ## @main
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
xorl %eax, %eax
movl $0, -4(%rbp)
movl $30, -8(%rbp)
popq %rbp
retq
.cfi_endproc
## -- End function
.section __DATA,__data
.globl _a ## @a
.p2align 2 …Run Code Online (Sandbox Code Playgroud) 环境:用于ARM Cortex m4f的GCC 4.7.3(arm-none-eabi-gcc).裸金属(实际上是MQX RTOS,但这里无关紧要).CPU处于Thumb状态.
这是我正在查看的一些代码的反汇编列表:
//.label flash_command
// ...
while(!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}
// Compiles to:
12: bf00 nop
14: f04f 0300 mov.w r3, #0
18: f2c4 0302 movt r3, #16386 ; 0x4002
1c: 781b ldrb r3, [r3, #0]
1e: b2db uxtb r3, r3
20: b2db uxtb r3, r3
22: b25b sxtb r3, r3
24: 2b00 cmp r3, #0
26: daf5 bge.n 14 <flash_command+0x14>
Run Code Online (Sandbox Code Playgroud)
常量(在扩展宏之后等)是:
address of FTFE_FSTAT is 0x40020000u
FTFE_FSTAT_CCIF_MASK is 0x80u
Run Code Online (Sandbox Code Playgroud)
这是使用NO优化(-O0)编译的,因此GCC不应该做任何花哨的事情......然而,我没有得到这个代码.回答后编辑:永远不要假设这一点.我的问题是因为关闭优化而产生了一种错误的安全感.
我读过"uxtb r3,r3"是截断32位值的常用方法.你为什么要截断它然后签名扩展?世界上的这个如何等同于C代码中的位掩码操作? …
我对汇编有一点了解。那么我先介绍一下代码,然后解释一下我的思路。
#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;
}
Run Code Online (Sandbox Code Playgroud)
好吧,首先让我吃惊的是我们没有将变量 a 和 b 用作 a + b。所以它们是不必要的,我们直接将整数相加。然而,如果计算机能够理解这一点,我想那将是非常可怕的。所以,我的问题是:在没有任何 addl 或类似命令的情况下,这个汇编代码是如何工作的?我们直接将立即数(或常量)整数 5 移至 eax 注册器。
另外,快速提问。那么最后两行之后的 a 和 b 变量会发生什么情况呢?它们在堆栈中的位置(或者也许我们可以将它们用作内存位置的“注册器”称为“注册器”)现在是空闲的,因为我们使用 malloc + free。这是真的还是至少合乎逻辑?我猜 popq %rbp 是关闭堆栈的命令。
正如我所说,我不是汇编专家。所以这些想法大部分都只是思考。谢谢!
我在c中有这么简单的代码:
#include <stdio.h>
void test() {}
int main()
{
if (2 < 3) {
int zz = 10;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我看到这段代码的汇编输出时:
test():
pushq %rbp
movq %rsp, %rbp
nop
popq %rbp
ret
main:
pushq %rbp
movq %rsp, %rbp
movl $10, -4(%rbp) // space is created for zz on stack
movl $0, %eax
popq %rbp
ret
Run Code Online (Sandbox Code Playgroud)
我从这里 得到了程序集(默认选项) 我看不出条件检查的指令在哪里?