泰州市网站建设_网站建设公司_MySQL_seo优化
2026/1/3 18:43:23 网站建设 项目流程

预处理

image

// a.c
#include <stdio.h>
#define MSG "Hello \
World!\n"
#define _str(x) #x
#define _concat(a, b) a##b
int main() {printf(MSG /* "hi!\n" */);
#ifdef __riscvprintf("Hello RISC-V!\n");
#endif_concat(pr, intf)(_str(RISC-V));return 0;
}

运行gcc -E a.c,gcc过程分为预处理-编译-汇编-链接-E就是做到预处理这一步

_str _concat都是函数式宏定义

ifdef ... #endif条件编译指令:__riscv:这是一个 编译器内置的预定义宏,只有在「编译 RISC-V 架构的程序」时,编译器才会自动定义这个宏;在 x86/x64(电脑常用)、ARM 等架构下,这个宏是未定义的。我电脑运行后 直接跳过他。

运行指令后变为:

# 6 "a.c"
int main() {printf("Hello World!\n" );printf("RISC-V");return 0;
}

image

verbose加入指令后会在终端输出两类关键信息:
1.gcc自身的版本,编译配置信息。2.gcc查找/加载头文件的全过程

终端输出:

#include "..." search starts here:
#include <...> search starts here:/usr/lib/gcc/x86_64-linux-gnu/11/include/usr/local/include/usr/include/x86_64-linux-gnu/usr/include

image
gcc -I 就是gcc一些新的头文件如果找不到了话用gcc -I 地址既可

image

前面其实都说到了,-risc_v部分

# 6 "a.c"
int main() {printf("Hello World!\n" );printf("Hello RISC-V!\n");printf("RISC-V");return 0;
}

image

执行

echo | gcc -dM -E - | sort > x86_64_macros.txt
echo | riscv64-linux-gnu-gcc -dM -E - | sort > riscv64_macros.txt
diff --color=auto x86_64_macros.txt riscv64_macros.txt

多出了这么一坨:
image

编译

image

语法解析与语义分析阶段该阶段对输入文件进行语法解析,将预处理记号转换为语法分析树。在生成语法分析树后,该阶段会执行语义分析,一方面计算表达式的类型,另一方面检查代码的语法合法性。此阶段不仅负责产生大部分编译器警告,还会捕获各类语法解析错误。该阶段的输出产物是抽象语法树(Abstract Syntax Tree,AST)。

image

!4 = !{i32 7, !"frame-pointer", i32 2} 没了,简单查了下这玩意是方便调试的,等于把它删了后gdb不太方便了

image

正如前文讲义所讲:volatile(禁止编译器对变量的优化)会被“严格执行”

image

源代码:

#include <stdio.h>
int main() { // compute 10 + 20int x = 10, y = 20;int z = x + y;printf("z = %d\n", z);return 0;
}
x86:.text.file	"b.c".globl	main                            # -- Begin function main.p2align	4, 0x90.type	main,@function
main:                                   # @main.cfi_startproc
# %bb.0:pushq	%rbp.cfi_def_cfa_offset 16.cfi_offset %rbp, -16movq	%rsp, %rbp.cfi_def_cfa_register %rbpsubq	$16, %rspmovl	$0, -4(%rbp)movl	$10, -8(%rbp)movl	$20, -12(%rbp)movl	-8(%rbp), %eaxaddl	-12(%rbp), %eaxmovl	%eax, -16(%rbp)movl	-16(%rbp), %esileaq	.L.str(%rip), %rdimovb	$0, %alcallq	printf@PLTxorl	%eax, %eaxaddq	$16, %rsppopq	%rbp.cfi_def_cfa %rsp, 8retq
.Lfunc_end0:.size	main, .Lfunc_end0-main.cfi_endproc# -- End function.type	.L.str,@object                  # @.str.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:.asciz	"z = %d\n".size	.L.str, 8.ident	"Ubuntu clang version 14.0.0-1ubuntu1.1".section	".note.GNU-stack","",@progbits.addrsig.addrsig_sym printf
risc_v32:.text.attribute	4, 16.attribute	5, "rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0".file	"b.c".globl	main                            # -- Begin function main.p2align	1.type	main,@function
main:                                   # @main
# %bb.0:addi	sp, sp, -48                 //开辟栈空间sd	ra, 40(sp)                      # 8-byte Folded Spillsd	s0, 32(sp)                      # 8-byte Folded Spilladdi	s0, sp, 48li	a0, 0sd	a0, -40(s0)                     # 8-byte Folded Spillsw	a0, -20(s0)li	a0, 10sw	a0, -24(s0)                     //从这开始复制相加li	a0, 20sw	a0, -28(s0)lw	a0, -24(s0)lw	a1, -28(s0)addw	a0, a0, a1sw	a0, -32(s0)lw	a1, -32(s0)
.LBB0_1:                                # Label of block must be emittedauipc	a0, %pcrel_hi(.L.str)addi	a0, a0, %pcrel_lo(.LBB0_1)call	printf@plt                 // 调用printf# kill: def $x11 killed $x10ld	a0, -40(s0)                     # 8-byte Folded Reloadld	ra, 40(sp)                      # 8-byte Folded Reloadld	s0, 32(sp)                      # 8-byte Folded Reloadaddi	sp, sp, 48ret
.Lfunc_end0:.size	main, .Lfunc_end0-main# -- End function.type	.L.str,@object                  # @.str.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:.asciz	"z = %d\n".size	.L.str, 8.ident	"Ubuntu clang version 14.0.0-1ubuntu1.1".section	".note.GNU-stack","",@progbits.addrsig.addrsig_sym printf
优化后:.text.attribute	4, 16.attribute	5, "rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0".file	"b.c".globl	main                            # -- Begin function main.p2align	1.type	main,@function
main:                                   # @main
# %bb.0:addi	sp, sp, -16sd	ra, 8(sp)                       # 8-byte Folded Spill
.LBB0_1:                                # Label of block must be emittedauipc	a0, %pcrel_hi(.L.str)addi	a0, a0, %pcrel_lo(.LBB0_1)li	a1, 30                       //直接加载立即数结果了call	printf@pltli	a0, 0ld	ra, 8(sp)                       # 8-byte Folded Reloadaddi	sp, sp, 16ret
.Lfunc_end0:.size	main, .Lfunc_end0-main# -- End function.type	.L.str,@object                  # @.str.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:.asciz	"z = %d\n".size	.L.str, 8.ident	"Ubuntu clang version 14.0.0-1ubuntu1.1".section	".note.GNU-stack","",@progbits.addrsig

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询