接着来实现C语言常用语法底层:
if else语句
条件控制
if(test_expr){
then_expr;
}else{
else_expr;
}
写成更像汇编的C语言版本:
if(!test_expr){
goto ELSE;
}
THEN:then_expr
goto DONE
ELSE:else_expr
DONE:
...
将goto 换成对应的jmp语句即是相关的汇编代码
条件传送
两个分支的值都计算出来,再根据判断条件将正确的结果赋给它,一般能节省时间
//不适合的例子
int t = p ? (*p) : 0; //解引用空指针
int t = condition ? Hard_exp1 : Hard_exp2; //时间开销反而更大
int t = x > 0? x *= 3 : x += 5; //使得传送结果变化
循环
do-while
LOOP:
body
if(test_expr) goto LOOP;
while
//两种实现
//1.jump to middle(-Og)
goto TEST;
LOOP:
body
TEST:
if(test_expr) goto LOOP;
//2.guarded-do(-O1)
//先测试初始条件是否满足,满足就转化为do-while实现,否则跳出
t = test_expr;
if(!t) goto DONE;
do
body
while(test_expr);
DONE:
for循环
比while多一个初始块和更新块,略
switch-case
- 跳转表
表的内容是地址,对应某一case所需执行代码的首地址
跳转表本身是连续的,方便索引
索引方式为:
jmp * .Label( , %rdi, 8) // switch对象为long类型
// jmp 默认跟地址, 加上* 表示从后面的内容里取得地址
// jmp %rax 不允许, 而 jmp * %rax允许
//与内存寻址有点不同
- 规则
首先将索引值偏移到0附近(加减某一值),大于某一阈值的直接落入default
在正确区间内,但没有指定操作的也在default块里
由于跳转表指向的内容往往连续,所以在没有break的情况下会继续执行下一个case
数组 指针 结构(struct)
- 多维数组与多级数组
多维数组:
多个行向量组合而成
在不同行向量间跳转的地址可以计算
每一个行向量就是一个普通的一维数组
多级数组:
上一级的数组是存放指向下一级数组首地址的指针
对应的C代码很像,但地址计算不一样 - 指针(略)
- 结构(看成 可以存放不同类型 的数组)
访问结构体的成员是 编译器做内存地址的偏移,从而得到正确的结果
往往需要内存对齐
内存对齐:
如果一个基本数据类型占用K字节,那么它的偏移量也应该是K的倍数
基地址和总大小也必须是K的倍数
C语言基础:条件控制、循环与结构的汇编对应与优化,
本文介绍了C语言中ifelse、循环(do-while、while、for和switch-case)、以及数组指针和结构的汇编对应,强调了条件传送中使用goto/jmp的技巧,并讨论了如何通过优化避免不必要的开销,如时间消耗和内存对齐问题。
1761

被折叠的 条评论
为什么被折叠?



