(二)数据传送指令
1)mov S, D
MOV 类中的指令将源操作数的值复制到目的操作数中。
2)pushl S
pushl %ebp 的行为等价于
subl $4, %esp Decrement stack pointer
Movl %ebp, %(esp) Store %ebp on stack
3)popl D
popl %eax 的行为等价与
movl (%esp), %eax Read %eax from stack
addl $4, %esp Increment stack pointer
(三)算术和逻辑操作指令
这些操作可分为四组:加载有效地址(load effective address)、一元操作(unary)、二元操作(binary)和移位(shifts)。
1)leal S, D
加载有效地址,其效果为D <—&S
2)neg D
D <— -D 取负(negative)D既是源又是目的
3)xor S, D
D <— D ^ S 第二个操作数既是源又是目的
4)sar k, D
D <— D >> k 算术右移(arithmetic right shift)
there are two names for the left shift instruction:sal and shl. Both have the same effect, filling from the right with zeros. The right shift instructions differ in thatsar performs an arithmetic shift (fill with copies of the sign bit), whereas shr performs a logical shift (fill with zeros). The destination operand of a shift operation can be either a register or a memory location.
(四)控制
条件语句、循环语句和分支语句,要求有条件的执行,根据数据测试的结果来决定操作执行的顺序。机器代码提供两种基本的低级机制来实现有条件的行为:测试数据值,然后根据测试的结果来改变控制流或者数据流。(it tests data values and then either alters the control flow or the data flow based on the result of these tests)
1、比较(Compare)
1)cmp S2, S1
基于S1 - S2与0的比较
2)test S2, S1
基于S1 & S2的测试
上两类指令只设置条件码而不改变任何其他寄存器。
2、跳转(Jump)
1)无条件跳转
The jmp instruction jumps unconditionally. It can be eitheradirect jump, where the jump target is encoded as part of the instruction, or anindirect jump, where the jump target is read from a register or a memory location.
jmp Label 直接跳转 例:jmp .L1
jmp *Operand 间接跳转 例:jmp *%eax
2)有条件跳转
jge Label等同jnl Label
大于或等于,跳转条件为~(SF ^ OF)
跳转指令有几种不同的编码:一、最常用的是PC相关的(PC-relative),它将目标指令的地址与紧跟在跳转指令后面那条指令的地址之间的差作为编码;二、给出“绝对”地址,用4个字节直接指出目标。
C语言与汇编的映射
(1)条件分支
对于if-else这种通用形式,汇编实现通常会使用下面的形式
C语言条件 |
用C语言goto语句描述控制流 |
|
if (test-expr) then-statement else else-statement
|
t = test-expr; if (!t) goto false; then-statement goto done; false: else-statement done: |
t = test-expr; if (t) goto true; else-statement goto done; true: then-statement done: |
(2)循环
汇编中使用条件测试与跳转组合起来实现循环的效果,大多数汇编器根据一个循环的do-while形式来产生循环代码。
C语言循环 |
用C语言描述goto语句控制流 |
do body-statement while (test-expr) |
loop: body-statement t = test-expr; if (t) goto loop; |
while (test-expr) body-statement
等价下面语句: if (!test-expr) goto done; do body-statement while (test-expr); done:
|
t = test-expr; if (!t) goto done; loop: body-statement t = test-expr; if (t) goto loop; done: |
for (init-expr; test-expr; update-expr) body-statement 等价下面语句(在使用continue时除外): init-expr; while (test-expr) { body-statement update-expr; } |
init-expr; t = test-expr; if (!t) goto done; loop: body-statement update-expr; t = test-expr; if (t) goto loop; done: |
(3)条件传送指令
实现条件操作的传统方法是利用控制的条件转移。当条件满足时,程序沿着一条执行路径执行,而当条件不满足时,就走另一条路径。数据的条件转移是一种替代的策略,该方法先计算条件操作的两个结果,然后再根据条件是否满足来选取一个(会产生副作用)。
C语言条件表达式 |
传统IA32抽象代码描述 |
条件传送抽象代码描述 |
v = test-expr ? then-expr : else-expr; |
if (!test-expr) goto false; v = then-expr; goto done; false: v = else-expr; done: |
vt = then-expr; v = else-expr; t = test-expr; if (t) v = vt; |
(4)switch语句
Switch语句可以根据一个整数索引值进行多重分支(multi-way branching)。可使用跳转表(jump table)这种数据结构使得实现更加高效。
int switch_eg(int x, int n) { int result = x; switch (n) { case 100: result *= 13; break; case 102: result += 10; case 103: result += 11; break; case 104: case 106: result *= result; break; default: result = 0; } return result; } // Translation into extended C int switch_eg_impl(int x, int n) { // Table of code pointers static void *jt[7] = { &&loc_A, &&loc_def, && loc_B, &&loc_C, &&loc_D, &&loc_def, &&loc_D}; unsigned index = n- 100; int result; if (index > 6) goto loc_def; // Multiway branch goto *jt[index]; loc_def: // Default case result = 0; goto done; loc_C: // Case 103 result = x; goto rest; loc_A: // Case 100 result = x * 13; goto done; loc_B: // Case 102 result = x + 10; rest: result += 11; goto done; loc_D: result = x * x; done: return result; }参考:《深入理解计算机系统》