int accum = 0;
int sum(int x, int y)
{
int t = x+y;
accum += t;
return t;
}
gcc –O2 -S code.c
得到
_sum:
pushl %ebp
movl %esp,%ebp
movl 12(%ebp),%eax
addl 8(%ebp),%eax
addl %eax, accum
movl %ebp,%esp
popl %ebp
ret
gcc –O2 -c code.c
可以得到machine code code.o
-O2
是优化程度
machine code可以objdump到assembly code
objdump -d code.o
汇编assembly
Operands:
x: Register %eax
y: Memory M[%ebp+8]
t: Register %eax
Instruction
addl 8(%ebp),%eax
Add 2 4-byte integers
Similar to expression x +=y
Return function value in %eax
Program Counter(%eip)
Address of the next instruction
e.g.
A=A+4
变成
movl 8(%ebp), %eax
addl $4, %eax
constant 4 叫 immediate, 如$0xffffffff
instructions
jmp
unconditional jump
Direct jump: jmp label
jmp .L
Indirect jump: jmp *Operand
jmp *%eax
jmp *(%eax)
conditional jump
jle .L4
.p2align 4,,7 align next instruction to multiple of 8
.L5:
movl %edx, %eax
sarl $1, %eax
subl %eax, %edx
testl %edx, %edx
jg .L5
.L4:
movl %edx, %eax
jle
:jump if less or equal
jg
:jump if greater than
前面要跟一个cmpl testl
之类的指令
Jump table
switch 实现
int switch_eg_goto ( int x)
{
unsigned xi = x-100;
int result = x ;
if ( xi >6 )
goto loc_def ;
goto jt[xi];
loc_a:
result *= 13 ;
goto done ;
loc_b:
result += 10 ;
loc_c:
result +=11;
goto done ;
loc_d:
result *= result ;
goto done ;
loc_def:
result = 0 ;
done:
return result ;
}
Assembly
.section .rodata
.align 4
.L10:
.long .L4 case 100: loc_a
.long .L9 case 101: loc_def
.long .L5 case 102: loc_b
.long .L6 case 103: loc_c
.long .L8 case 104: loc_d
.long .L9 case 105: loc_def
.long .L8 case 106: loc_d
lea –100(%edx), %eax
cmpl $6, %eax
ja. L9
jmp *.L10(, %eax, 4)
.L4:
leal ( %edx, %edx, 2), %eax
leal (%edx, %eax, 4), %edx
jmp .L3
.L5:
addl $10, %edx
.L6:
addl $11, %edx
jmp .L3
.L8:
imull %edx, %edx
jmp .L3
.L9:
xorl %edx, %edx
.L3:
movl %edx, %eax
procedure call
When a program is invoked:
The OS allocates space for the program
The code is loaded into part of the space
The OS jumps to the entry point (i.e., “main”)
An invocation of procedure P is an activation of P
Activation Trees
The information needed to manage one procedure activation is called an activation record (AR) or frame
If procedure F calls G, then G’s activation record contains a mix of info about F and G.
A stack frame is delimited by
The frame pointer %ebp
The stack pointer %esp
Caller saved registers
%eax, %edx, %ecx
Saved by caller
Callee can use these registers freely
The contents in these registers may be changed after return
Caller must restore them if it tries to use them after calling
Callee saved registers
%ebx, %esi, %edi
Callee must save them before using
Callee must restore them before return
Save caller save registers (%eax, %edx, %ecx)
Push actual arguments from right to left
Call instruction
Save return address
Transfer control to callee
pushl argument n
...
pushl argument 1
call callee
call
call label (direct)
call *operand (indirect)
Save return address in the stack
Jump to the entry to callee
init call frame
pushl %ebp
movl %esp, %ebp
save callee saved register
adjust %esp to allocate space for local variables and temporaries
destruct call frame
restore callee saved registers
movl %ebp, %esp
popl %ebp
ret
Integeral return value is in the %eax
restore callee saved registers
leave
ret
e.g.
1 int swap_add(int *xp, int *yp)
2 {
3 int x = *xp;
4 int y = *yp;
5
6 *xp = y;
7 *yp = x;
8 return x + y;
9 }
11 int caller()
12 {
13 int arg1 = 534;
14 int arg2 = 1057;
15 int sum = swap_add(&arg1, &arg2);
16 int diff = arg1 - arg2;
17
18 return sum * diff;
19 }
1 leal -4(%ebp),%eax
Compute &arg2
2 pushl %eax
Push &arg2
3 leal -8(%ebp),%eax
Compute &arg1
4 pushl %eax
Push &arg1
5 call swap_add
Call the swap_add function
swap_add:
1 pushl %ebp Save old %ebp
2 movl %esp,%ebp
Set %ebp as frame pointer
3 pushl %ebx
Save %ebx
5 movl 8(%ebp),%edx Get xp
6 movl 12(%ebp),%ecx Get yp
7 movl (%edx),%ebx Get x
8 movl (%ecx),%eax Get y
9 movl %eax, (%edx) Store y at *xp
10 movl %ebx, (%ecx) Store x at *yp
11 addl %ebx,%eax Set return value = x+y
12 popl %ebx Restore %ebx
13 movl %ebp, %esp Restore %esp
14 popl %ebp Restore %ebp
15 ret Return to caller
Out-of-Bounds Memory References
1 /* Implementation of library function gets() */
2 char *gets(char *s)
3 {
4 int c;
5 char *dest = s;
6 while ((c = getchar()) != ’\n’ && c != EOF)
7 *dest++ = c;
8 *dest++ = ’\0’; /* Terminate String */
9 if (c == EOF)
10 return NULL;
11 return s;
12 }
13
14 /* Read input line and write it back */
15 void echo()
16 {
17 char buf[4]; /* Way too small ! */
18 gets(buf);
19 puts(buf);
20 }
把esp和return address冲掉,就可以让程序返回到想要的位置,就是lab3的内容
Array
XA:起点address
Array element i is stored at address
XA + sizeof(T) * i
二维数组
C里struct union(公用一块内存,但是重新翻译)都是堆里的,用malloc和calloc分配内存,free来释放,注意有alignment的问题
%eflag:
CF: Carry Flag
The most recent operation generated a carry out of the most significant bit
Used to detect overflow for unsigned operations
OF: Overflow Flag
The most recent operation caused a two’s complement overflow — either negative or positive
ZF: Zero Flag
The most recent operation yielded zero
SF: Sign Flag
The most recent operation yielded a negative value
Implicit Setting By Arithmetic Operations
addl Src,Dest
C analog: t = a+b
CF set if carry out from most significant bit
Used to detect unsigned overflow
ZF set if t == 0
SF set if t < 0
OF set if two’s complement overflow
(a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0)
lea instruction
has no effect on condition codes
Xorl instruction
The carry and overflow flags are set to 0
Shift instruction
carry flag is set to the last bit shifted out
Overflow flag is set to 0
Explicit Setting by Compare Instruction
cmpl Src2,Src1
cmpl b,a like computing a-b without setting destination
CF set if carry out from most significant bit
Used for unsigned comparisons
ZF set if a == b
SF set if (a-b) < 0
OF set if two’s complement overflow
(a>0 && b<0 && (a-b)<0) ||
(a<0 && b>0 && (a-b)>0)
Explicit Setting by Test instruction
testl Src2,Src1
Sets condition codes based on value of Src1 & Src2
Useful to have one of the operands be a mask
testl b,a like computing a&b without setting destination
ZF set when a&b == 0
SF set when a&b < 0
Virtual memory: 假装有一大块array一样的存储空间
所以M[addr]来表示addr里存的value
取多长看代码,比如int取4byte
还要看一下little endian还是big endian
processor state
register
32位老机器
64位新机器扩展大小为64位,r开头,而且加了8个register
%rip
是指向当前一条指令
%rsp
是指向当前栈顶
%eax
is used to pass the result of callee to caller
Stack
cast:bit不变,重新翻译
movl %eax,-0x44(%ebp,%edx,4)
-0x44(%ebp,%edx,4)
:%ebx+4*%edx-0x44
参考文献
复旦大学ICS课PPT
CMU ICS课PPT