comp40 · 2020. 9. 29. · mov %edi, %eax shl $0x4, %eax retq assembly instructions: int times16(...

Post on 25-Mar-2021

3 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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

top related