comp40 · 2020. 9. 29. · mov %edi, %eax shl $0x4, %eax retq assembly instructions: int times16(...
TRANSCRIPT
COMP40Assembly Language (continued...)
Thesmallexample:
int times16( int i ) {
return i * 16; }
89 f8 c1 e0 04 c3
Actualmachineinstructions:
mov %edi, %eax shl $0x4, %eax retq
Assemblyinstructions:
mov %edi, %eax shl $0x4, %eax retq
Assemblyinstructions:
int times16( int i ) {
return i * 16; }
89 f8 c1 e0 04 c3
Actualmachineinstructions:
Thesmallexample:
mov %edi, %eax shl $0x4, %eax retq
Assemblyinstructions:
int times16( int i ) {
return i * 16; }
89 f8 c1 e0 04 c3
Actualmachineinstructions:
Thesmallexample:
mov %edi, %eax shl $0x4, %eax retq
Assemblyinstructions:
int times16( int i ) {
return i * 16; }
89 f8 c1 e0 04 c3
Actualmachineinstructions:
Thesmallexample:
mov %edi, %eax shl $0x4, %eax retq
Assemblyinstructions:
int times16( int i ) {
return i * 16; }
89 f8 c1 e0 04 c3
Actualmachineinstructions:
Thesmallexample:
mov %edi, %eax shl $0x4, %eax retq
Assemblyinstructions:
int times16( int i ) {
return i * 16; }
89 f8 c1 e0 04 c3
Actualmachineinstructions:
Thesmallexample:
1.)Addressingmodes
3.)Controlflow
2.)Workingthestack
1.)Addressingmodes
3.)Controlflow
2.)Workingthestack
Addressingmodes:
%rdi // contents of rdi is data
Inuse: movq %rdi, %rax Assume%rdiholdsvariablexand%raxholdsy,thenhisimplements:
long x, y; y = x;
movq “quad” length move b → byte w → 2 bytes (short) l → long (4 bytes not 8!) q → quad (8 bytes)
Addressingmodes:
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
%rdi // contents of rdi is data
Inuse: movq (%rax), %rbx Assume%raxholdsvariable&xand%rbxholdsy,thenthisimplements:
long *xp = &x; long y; y = *xp;
The source or the target can reference memory…but not both. Copying from memory to memory takes two instructions (into register and back out).
Addressingmodes:
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
%rdi // contents of rdi is data
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
Addressingmodes:
%rdi // contents of rdi is data
Inuse: movq 0x10(%rax), %rbx struct s { long m1, m2, m3, m4) } *sp
long y = sp -> m3;
Yes, (0x10 %rax) probably feels more logical here... but alas.
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
Addressingmodes:
%rdi // contents of rdi is data
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
Addressingmodes:
%rdi // contents of rdi is data
Inuse: movq 0x4089a0(,%rax, 8), %rbx long arr[1000]; /* assume at 0x4089a0 */ long i; /* array index in %rax*/ long y; /* move target in %rbx */ y = arr[i]; /* all in one assembler mov! */
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
Addressingmodes:
%rdi // contents of rdi is data
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
Addressingmodes:
%rdi // contents of rdi is data
Inuse: movl (%ebx,%ecx, 4), %edx int *ebx; int edx = ebx[ecx]
// edx <- *(ebx + (ecx * 4))
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
Addressingmodes:
%rdi // contents of rdi is data
Inuse: movl (%ebx,%ecx, 4), %edx // edx <- *(ebx + (ecx * 4)) leal (%ebx,%ecx, 4), %edx // edx <- (ebx + (ecx * 4))
int *ebx; int *edx = &(ebx[ecx])
int x, y, z; z = x + (y * 4)
OR
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
Addressingmodes:
%rdi // contents of rdi is data
Inuse: movb (%bx,%cx, 1), %dx // dx <- *(bx + (cx * 1))
leab (%bx,%cx, 1), %dx // dx <- (bx + (cx * 1))
char *bx; char *dx = &(bx[cx])
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
Addressingmodes:
%rdi // contents of rdi is data
(%rax) // data pointed to by rax 0x10(%rax) // get *(16 + rax) $0x4089a0(, %rax, 8) // Global array index of 8-byte things (%ebx, %ecx, 4) // Add base and scaled index 4(%ebx, %ecx, 2) // Add base and scaled index plus offset 4
Addressingmodes:
%rdi // contents of rdi is data
Inuse: movl 4(%ebx,%ecx, 2), %edx // edx <- *(4 + ebx + (ecx * 2))
A( B, C, D)
A + B + (C * D))
=
A( B, C, D)
A + B + (C * D))
=
A( B, C, D)
A + B + (C * D))
=
A( B, C, D)
A + B + (C * D))
=
A( B, C, D)
A + B + (C * D))
=
A( B, C, D)
A + B + (C * D))
=
1.)Addressingmodes
3.)Controlflow
2.)Workingthestack
1.)Addressingmodes
3.)Controlflow
2.)Workingthestack
Stack
Text(code)
Staticinitialized
Staticuninitialized
Heap(malloc’d)
argv,environ
0
7fffffffffff
1.)Addressingmodes
3.)Controlflow
2.)Workingthestack
Stack
argv,environ
0
7fffffffffff
arg3
arg2
arg1Functioncallismade
returnaddress%esp
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
arithneedstouseregister%ebp,sowepushitsvalueontothestackandrestoreitlater.
Stack
argv,environ
0
7fffffffffff
arg3
arg2
arg1
returnaddress%esp
%ebp
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
Nowwecanuse%ebp,asamarkofwhereourstackpointerstarted
%ebp =
Stack
argv,environ
0
7fffffffffff
arg3
arg2
arg1
returnaddress
%esp %ebp
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
%ebp =
Stack
argv,environ
0
7fffffffffff
arg3
arg2
arg1
returnaddress
%ebp +4
+12
%ebp =
Stack
argv,environ
0
7fffffffffff
arg3
arg2
arg1
returnaddress
%ebp +4
+12
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
// %eax = x
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
// %eax = x // %edx = y
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
// %eax = x // %edx = y
// %ecx = x+y
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
// %eax = x // %edx = y
// %ecx = x+y // %edx = y*3
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
// %eax = x // %edx = y
// %ecx = x+y // %edx = y*3 // %edx = y*16
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
// %eax = x // %edx = y
// %ecx = x+y // %edx = y*3 // %edx = y*16 // %ecx = z+t1
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
// %eax = x // %edx = y
// %ecx = x+y // %edx = y*3 // %edx = y*16 // %ecx = z+t1
// %eax = 4+t4+x
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
// %eax = x // %edx = y
// %ecx = x+y // %edx = y*3 // %edx = y*16 // %ecx = z+t1
// %eax = 4+t4+x // %eax = t2*t5
int arith(int x, int y, int z) {
int t1 = x + y; int t2 = z + t1; int t3 = x + 4; int t4 = y * 48;
int t5 = t3 + t4; int rval = t2 * t5;
return rval; }
arith: pushl %ebp movl %esp,%ebp
movl 12(%ebp),%eax movl 16(%ebp),%edx leal (%edx,%eax),%ecx leal (%edx,%edx,2),%edx sall $4,%edx addl 20(%ebp),%ecx leal 4(%edx,%eax),%eax imull %ecx,%eax
movl %ebp,%esp popl %ebp ret
// %eax = x // %edx = y
// %ecx = x+y // %edx = y*3 // %edx = y*16 // %ecx = z+t1
// %eax = 4+t4+x // %eax = t2*t5
%esp =
Stack
argv,environ
0
7fffffffffff
arg3
arg2
arg1
returnaddress
%ebp %ebp
Stack
argv,environ
0
7fffffffffff
arg3
arg2
arg1
returnaddress
%esp =
Stack
argv,environ
0
7fffffffffff
arg3
arg2
arg1
%esp =
Whenafunctioniscalled,thestackpointermustbeamultipleof16. returnaddress
Stack
argv,environ
0
7fffffffffff
arg3
arg2
arg1%esp = Whenafunctioniscalled,thestack
pointermustbeamultipleof16. returnaddress
wastedspace
notamultipleof16!
Stack
argv,environ
0
7fffffffffff
arg3
arg2
arg1
%esp =
Whenafunctioniscalled,thestackpointermustbeamultipleof16.
sub $8,%rsp
returnaddress
wastedspace
add $8,%rsp
...
1.)Addressingmodes
3.)Controlflow
2.)Workingthestack
1.)Addressingmodes
3.)Controlflow
2.)Workingthestack
Controlflow:
void ifelse(int a, int b) {
if (a > b) func1(a); else func2(b);
}
ifelse: subq $8, %rsp cmpl %esi, %edi jle .L2 call func1 jmp .L1
.L2: movl %esi, %edi call func2
.L1: addq $8, %rsp ret
ifelse: subq $8, %rsp cmpl %esi, %edi jle .L2 call func1 jmp .L1
.L2: movl %esi, %edi call func2
.L1: addq $8, %rsp ret
Controlflow:
void ifelse(int a, int b) {
if (a > b) func1(a); else func2(b);
}
ifelse: subq $8, %rsp cmpl %esi, %edi jle .L2 call func1 jmp .L1
.L2: movl %esi, %edi call func2
.L1: addq $8, %rsp ret
void ifelse(int a, int b) {
if (a > b) func1(a); else func2(b);
}
Controlflow:
void ifelse(int a, int b) {
if (a > b) func1(a); else func2(b);
}
ifelse: subq $8, %rsp cmpl %esi, %edi jle .L2 call func1 jmp .L1
.L2: movl %esi, %edi call func2
.L1: addq $8, %rsp ret
Controlflow:
Buthowdoweknowtheresultofthiscompare?
Theflagsregistertrackscomparisons:
62
Example:ZeroflagsetiflastresultiszeroorlastcompareisequalConditionaljumpsandmovestesttheflags
ifelse: subq $8, %rsp cmpl %esi, %edi jle .L2 call func1 jmp .L1
.L2: movl %esi, %edi call func2
.L1: addq $8, %rsp ret
void ifelse(int a, int b) {
if (a > b) func1(a); else func2(b);
}
Controlflow:
Summary
• Ccodecompiledtoassembler
• Datamovedtoregistersformanipulation
• Conditionalandjumpinstructionsforcontrolflow
• Stackusedforfunctioncalls
• Compilersplayallsortsoftrickswhencompilingcode