Documente Academic
Documente Profesional
Documente Cultură
L12
movl x, %eax
cmpl y, %eax
jg L12
movl $27, a
ret
movl $19, b
ret
Loops
while (some long expression E) {
some long statement S;
}
converted to
L1:
L3:
jmp L3
dozens of instructions for S
dozens of instructions for E
testl %eax, %eax
jnz L1
assembly instructions are not necessarily in the same order as the original C code
do S
while (E);
converted into the same instructions but without the initial jmp L3
for (E1, E2, E3)
S;
converted to
L12:
L10:
e1
jmp L10
S
e3
e2
tstl %eax %eax
jnz L12
e1
jmp L9
e2
tstl %eax, %eax
jnz L90
S
e3
switch (E) {
case -1: S1; break;
case 0: S2; break;
default: S3; break;
}
converted to
e:
L12:
L20:
%eax
tstl %eax, eax
jz L12
cmpl $-1, %eax
je L20
S3
jmp L100
S2
jmp L100
S1
jmp L12
L100:
or can jump directly to the memory location that a register points to based on a
table
e
%eax (1, 19, 57, 97231)
19
57
L3
L19
L100
stack pointer pointing to an odd value not aligned with the boundaries of each word
is forbidden by the x86 ABI
selection overlaps another
word
%esp
stack alignment
x86 multiple of 8 on procedure entry
x86-64
multiple of 16
Recursion
ex. function f calls itself:
main f g h f
stack:
fs stuff
hs stuff
gs stuff
fs stuff
mains stuff
A frame is a contiguous stack region associated with a procedure instance
outgoing args
%eb
p
0
4
8
12
fs frame
fs locals
fs temps
saved %ebp
return address
fs arg 1
hs frame
fs arg 2
all args
pushl %ebp
movl %esp, %ebp
xorl
popq
popq
jmp
L12
%eax, %eax
%rbx
%rbp
visit
rep ret
x86-64 registers
%rax
return value (caller saved)
%rbx
callee saved
%rcx
arg #4
%rdx
arg #3
%rsi
arg #2
%rdi
arg #1
%rsp
stack pointer
%rbp
callee saved
%r8
arg #5
%r9
arg #6
%r10
callee saved
%r11
(used for linking)
%r1215
callee saved
callee saved - caller cannot change register, except temporarily, callee can set them
and doesnt need to restore
C pointers
bigsub:
mull
addl
ret
8(%esp), %eax
4(%esp), %edx
(%eax, %eax, 2), %eax
(%edx, %edx, 4), %eax
eax = 3*i
eax = eax*4 + a
Nested Arrays
double a[100][200];
&a[i][j] = (a + i * 1600)*8
memory representation:
a[99]
a[99]
[199]
[198]
a[0][199]
a[0][2]
a[0][1]
Structures
Heterogeneous components
# of elements fixed at compile time
struct {
char c;
int i;
long l;
}
each variable is padded to be properly aligned in memory
a[0][0]
[
c in location 10000
i in location 10004
l i???c]
struct s {
char c;
int i;
char d;
int j;
}
int* foo(struct s, *p) {
return &p->j;
}
equivalent to (int*)((char*)p + 12)
in memory:
[ j| ?|d| i| ?|c]
12
8 4
0
struct s a[100];
&a[i] equivalent to a + 8*i because char is size 8
can check alignment of things in C11 with
gcc -std=gnu11
_Alignof(struct s)
signed int i:9;
signed int foo:1;
register int i = 27;