/*********************************
* File Name: func.c
*********************************/
int func (int x)
{
if (x == 0)
{
x += 5;
}
else
{
x += 6;
}
return (x);
}
經過以下的編譯,及觀察結果
$ gcc -O2 func.c -o func.o
$
$ objdump -S func.o
func.o: file format elf32-i386
Disassembly of section .text:
00000000
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 08 mov 0x8(%ebp),%eax
6: 85 c0 test %eax,%eax
8: 75 07 jne 11
a: 5d pop %ebp
b: b8 05 00 00 00 mov $0x5,%eax
10: c3 ret
11: 5d pop %ebp
12: 83 c0 06 add $0x6,%eax
15: c3 ret
$
$
以上位址6,8中(test, jne)是C語言編譯成組合語言
if (...) .... else ...很典型的編譯方式....(這是經過最佳化)
instruction jne, je 會根據Zero flags來做跳躍(換句話說是PC的重新指定)...
這邊可以"想像"為...je, jne會把zero flags當作之前的運算結果是否為true,false。
所謂"之前的運算"是指test instruction。
1. 當Zero flag為0時,執行
je 11
會跳躍到11的位址
jne 11
不會跳躍到11的位址,而是繼續執行下一行。
2. 當Zero flag不為0時,執行
je 11
不會跳躍到11的位址,而是繼續執行下一行。
jne 11
會跳躍到11的位址。
3. Zero flags的設定...
In the x86 assembly language, the TEST instruction performs a bitwise AND on two operands. The flags SF, ZF, PF, CF, OF and AF are modified while the result of the AND is discarded.
Instruction TEST Operation
TEMP <-- and="" font="" src1="" src2="">-->
SF <-- font="" msb="">-->
IF TEMP = 0
THEN ZF <-- 1="" font="">-->
ELSE ZF <-- 0="" font="">-->
FI:
PF <-- bitwisexnor="" font="">-->
CF <-- 0="" font="">-->
OF <-- 0="" font="">-->
(*AF is Undefined*)
所以C語言跟組合語言的對照如下...
int func1 (int x) /* mov 0x8(%ebp), %eax */
{
if (x == 0) /* test %eax, %eax; jne 0x11 */
{
x += 5;
}
else /* address 0x11 */
{
x += 6;
}
return (x);
}
int func2 (int x) /* mov 0x8(%ebp), %eax */
{
if (x != 0) /* test %eax, %eax; je 0x11*/
{
x += 5;
}
else /* address 0x11 */
{
x += 6;
}
return (x);
}
No comments:
Post a Comment