if
从最简单的if语句开始。
#include <stdio.h>
int main(void)
{
int a;
scanf("%d",&a);
if((a&1)==0)
{
printf("is even!");
}
return 0;
}
最简单的if语句如上。我们将其转化为汇编。
.section .rodata
.LC0:.string "%d"
.LC1:.string "is even!"
.text
.global main
main:
pushl %ebp
movl %esp,%ebp
subl $4,%esp
leal -4(%ebp),%eax
pushl %eax
pushl $.LC0
call scanf
addl $8,%esp
movl -4(%ebp),%eax
andl $1,%eax
cmpl $0,%eax
jne .L1
pushl $.LC1
call printf
addl $4,%esp
.L1:
movl $0,%eax
leave
ret
最新用到的指令。
指令 | 基于 | 描述 |
---|---|---|
cmpl S2,S1 | S1-S2 | 比较 |
注意这里的S2是减数,S1是被减数,与我们使用的惯例是相反的。
cmpl 指令会将S1减去S2,但只设置条件码,不改变参数的值。
条件码
除了整数寄存器,CPU还维护着一组单个位的条件码寄存器,它们描述了最近的算数运算或逻辑运算操作的属性。常用的条件码有:
CF:进位标志。
ZF:零标志。
SF:符号标志。
OF:溢出标志。
跳转
指令 | 跳转条件 | 描述 |
---|---|---|
jmp Label | 1 | 直接跳转 |
jmp *Operand | 1 | 间接跳转 |
je Label | ZF | 相等/零 |
jne Label | ~ZF | 不相等/非零 |
js Label | SF | 负数 |
jns Label | ~SF | 非负数 |
jg Label | (SF^OF)&ZF | 大于(有符号>) |
jge Label | ~(SF^OF) | 大于等于(有符号>=) |
jl Label | SF^OF | 小于(有符号<) |
jle Label | (SF^OF) | ZF |
ja Label | CF&ZF | 超过(无符号> |