访问条件码
指令 | 同义名 | 跳转条件 | 描述
-|-|-|-
\(jmp \quad Label\) | | 1 | 直接跳转
\(jmp \quad *Operand\) | | 1 | 间接跳转
\(je \quad Label\) | \(jz\) | \(ZF\) | 相等/零
\(jne \quad Label\) | \(jnz\) | \(\sim ZF\) | 不相等/非零
\(js \quad Label\) | | \(SF\) | 负数
\(jns \quad Label\) | | \(\sim SF\) | 非负数
\(jg \quad D\) | \(jnle\) | \(D \leftarrow \sim(SF \land OF) \& \sim ZF\)| 大于(有符号>)
\(jge \quad D\) | \(jnl\) | \(D \leftarrow \sim(SF \land OF)\)| 大于等于(有符号 >=)
\(jl \quad D\) | \(jnge\) | \(D \leftarrow SF \land OF\)| 小于(有符号<)
\(jle \quad D\) | \(jng\) | \(D \leftarrow \sim(SF \land OF) \mid ZF\)| 小于等于(有符号 <=)
\(ja \quad D\) | \(jnbe\) | \(D \leftarrow \sim CF \& \sim ZF\) | 大于(无符号>)
\(jae \quad D\) | \(jnb\) | \(D \leftarrow \sim CF\) | 大于等于(无符号>=)
\(jb \quad D\) | \(jnae\) | \(D \leftarrow CF\) | 小于(无符号<)
\(jbe \quad D\) | \(jna\) | \(D \leftarrow CF \mid ZF\) | 小于等于(无符号<=)
跳转指令一般将目标指令的地址与紧跟在跳转指令后面那条指令之间的差作为编码
有下C代码
反汇编二进制代码
think@pc$ gcc -O0 -c foo.c think@pc$ objdump -S foo.o foo.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <foo>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp) b: eb 11 jmp 1e <foo+0x1e> d: 83 7d fc 01 cmpl $0x1,-0x4(%rbp) 11: 75 07 jne 1a <foo+0x1a> 13: b8 01 00 00 00 mov $0x1,%eax 18: eb 0f jmp 29 <foo+0x29> 1a: 83 45 fc 01 addl $0x1,-0x4(%rbp) 1e: 83 7d fc 02 cmpl $0x2,-0x4(%rbp) 22: 7e e9 jle d <foo+0xd> 24: b8 00 00 00 00 mov $0x0,%eax 29: 5d pop %rbp 2a: c3 retq看第一个跳转指令在地址 b, 跳转的地址为 1e, 其值为 11 + d, 这里比较特殊的是
地址是无符号类型
相对地址为有符号类型
看内存地址为 0x24 的那条 jle 指令, 其跳转地址为 d = 24(unsigned) + e9(-17,signed)。与 PC计数器 指向下一条执行的指令的现象相符合,这样就可以比较轻易的完成链接操作。
过程对于我们一般的认识就是过程可以理解为函数调用。
过程的机器级支持需要处理多种属性
传递控制。在程序进入过程\(Q\)时\(PC\)必须设置为\(Q\)的代码起始地址,返回时要把\(PC\)设置为\(P\)中调用\(Q\)后面的那条指令的地址。
传递参数。\(P\)必须能够向\(Q\)提供一个或者多个参数,\(Q\)必须能够向\(P\)返回一个值。
分配和释放内存。在开始时,Q可能需要为局部变量分配空间,而在返回前,又必须释放这些分配的内存。
栈的弹出和压入指令 指令 效果 描述\(pushq \quad S\) \(R[\%rsp] \leftarrow R[\%rsp] - 8 \\ M[R[\%rsp]] \leftarrow S\) 四字入栈
\(popq \quad D\) \(D \leftarrow M[R[\%rsp]] \\ R[\%rsp] \leftarrow R[\%rsp] + 8\) 四字出栈