考研,408,组成原理,程序的机器级表示
考研 408 大纲《计算机组成原理》指令系统部分新增的 高级语言程序于机器级代码直接的对应 考点:
- 选择结构语句的机器级表示
- 循环结构语句的机器级表示
- 过程(函数)调用对应的机器基本表示
主要看 CSAPP 整理了一下。
流程控制
if-else
csapp2e.Zh_CN P130: 3.6.4
C 语言模版:
if (test_expr)
then_statement
else
else_statement
Goto 版本:
t = test_expr;
if (!t)
goto FALSE;
then_statement
goto DONE;
FALSE:
else_statement
DONE:
注意这里的 FALSE 是个标签,不是 0.
如果思路反过来,测试 t 为真时 goto 跳转到 TRUE 去跑 then_statement
,虽然也可以,但对于没有 else 的 if 就会很诡异。
汇编(ATT 风格 MOV S, D
表示 S -> D):
[test_expr] # 测试语句: e.g. cmp
jnc FALSE # 不满足条件时跳转: e.g. je
[then_statement]
jmp DONE
FALSE:
[else_statement]
DONE:
约定:我们用 jc
、jnc
来代表某个“条件跳转”指令,具体可能是 je
,jg
,jl
等等。
jc
: 满足条件时跳转,对应if (test_expr) goto L;
;jnc
:不满足条件时跳转,对应if (!t) goto L;
。
我们在汇编里用 [test_expr]
这种表示实现 C 中的 test_expr
的一块代码。
e.g. if-else
int absdiff(int x, int y) {
if (x < y)
return y - x;
else
return x - y;
}
goto:
int absdiff_goto(int x, int y) {
int result;
if (x >= y)
goto x_ge_y;
result = y - x;
goto done;
x_ge_y:
result = x - y;
done:
return result;
}
asm:
movl 8(%ebp), %edx # x
movl 12(%ebp), %eax # y
cmpl %eax, %edx # x:y 做 x-y 来比较
jge X_GE_Y # x >= y 则跳转
subl %edx, %eax # y-x
jmp DONE
X_GE_Y:
subl %eax, %edx # x-y
movl %edx, %eax
DONE:
[补充]条件传送
对于用三目运算符完成的简单的条件,例如 min = (x < y ? x : y);
把这个翻译成 if-else,用上面的那种手法去翻译,其实对流水线并不友好。控制冒险如果错了惩罚时间相当长。
现代机器上有「条件传送」指令:cmov
。就是类似于条件跳转 jc,cmov 在满足条件的时候做 mov。
具体的 cmov 族也是有 cmove
、cmovl
、cmovge
等等这些。
利用这个指令,可以把两个分支全算了,最后利用 cmov 来选一个结果。就不用去控制冒险了:
v = test_expr ? then_expr : else_expr;
/* ⬇️ */
vt = then_expr;
v = else_expr;
t = test_expr;
if (t) v = vt; // 用 cmov 实现
但注意,这个不是通用的!!不是所有三目运算都可以这么翻译,一般只有这种纯运算、没有副作用的才能这么搞。
do-while
csapp2e.Zh_CN P130: 3.6.5
C:
do
body_statement