|
![collapse V](Expanded.png) |
|
Lecture 20 — addressing and arithmetic in x86 assembly
|
|
|
![collapse V](Expanded.png) |
|
hw5 questions
|
|
|
![collapse V](Expanded.png) |
|
should freemem make sure it’s argument is a valid pointer previously allocated by getmem?
|
|
|
![*](LeafRowHandle.png) |
|
no, freemem should check for NULL, but otherwise just assume the argument is valid
|
|
|
![collapse V](Expanded.png) |
|
how do you store the memory for each block?
|
|
|
![*](LeafRowHandle.png) |
|
the memory is not stored explicitly anywhere
|
|
|
![*](LeafRowHandle.png) |
|
when you have a pointer to a block header, you actually have a pointer to the start of a larger block of memory
|
|
|
![*](LeafRowHandle.png) |
|
you just happen to be using the first 16 bytes of that memory as your header struct
|
|
|
![collapse V](Expanded.png) |
|
how does the free list get started?
|
|
|
![*](LeafRowHandle.png) |
|
declare global variable that points to first block on the list in mem_impl.h
|
|
|
![*](LeafRowHandle.png) |
|
check if this pointer is NULL at the start of getmem
|
|
|
![*](LeafRowHandle.png) |
|
if so, use malloc to create the first block on the list
|
|
|
![collapse V](Expanded.png) |
|
how does bench work?
|
|
|
![*](LeafRowHandle.png) |
|
for each trial (of which there are ntrials), generate a random number to decide if this trial will be a call to getmem or freemem
|
|
|
![*](LeafRowHandle.png) |
|
there should be a pctget chance of choosing a getmem call
|
|
|
![*](LeafRowHandle.png) |
|
if it’s getmem, generate a second random number to choose whether the request will be large or small, and a third random number to choose the exact size
|
|
|
![collapse V](Expanded.png) |
|
if it’s freemem, generate a second random number to choose which previous allocation to free
|
|
|
![*](LeafRowHandle.png) |
|
if there are no previous allocations, do nothing, but still count it as a trial
|
|
|
![collapse V](Expanded.png) |
|
exercise:
|
|
|
![*](LeafRowHandle.png) |
|
memory: address value 0x100 0xFF 0x104 0xAB 0x108 0x13 0x10C 0x11
|
|
|
![*](LeafRowHandle.png) |
|
registers register value %rax 0x100 %rcx 0x1 %rdx 0x3
|
|
|
![collapse V](Expanded.png) |
|
what is the value of the following operands:
|
|
|
![collapse V](Expanded.png) |
|
%rax
|
|
|
![*](LeafRowHandle.png) |
|
0x100 // register
|
|
|
![collapse V](Expanded.png) |
|
0x104
|
|
|
![*](LeafRowHandle.png) |
|
0xAB // absolute address
|
|
|
![collapse V](Expanded.png) |
|
$0x108
|
|
|
![*](LeafRowHandle.png) |
|
0x108 // immediate
|
|
|
![collapse V](Expanded.png) |
|
(%rax)
|
|
|
![*](LeafRowHandle.png) |
|
0xFF // address 0x100
|
|
|
![collapse V](Expanded.png) |
|
4(%rax)
|
|
|
![*](LeafRowHandle.png) |
|
0xAB // address 0x104
|
|
|
![collapse V](Expanded.png) |
|
understanding swap
|
|
|
![collapse V](Expanded.png) |
|
complete addressing mode
|
|
|
![collapse V](Expanded.png) |
|
D(Rb,Ri,S)
|
|
|
![*](LeafRowHandle.png) |
|
D: constant integer offset (“displacement”)
|
|
|
![*](LeafRowHandle.png) |
|
Rb: base register (any)
|
|
|
![*](LeafRowHandle.png) |
|
Ri: index register (any except %rsp)
|
|
|
![*](LeafRowHandle.png) |
|
S: scale (1, 2, 4, or 8)
|
|
|
![*](LeafRowHandle.png) |
|
retrieves value at memory location Rb + S•Ri + D
|
|
|
![collapse V](Expanded.png) |
|
parameters have default values when omitted
|
|
|
![collapse V](Expanded.png) |
|
examples:
|
|
|
![*](LeafRowHandle.png) |
|
for (Rb, Ri), S=1 and D=0
|
|
|
![*](LeafRowHandle.png) |
|
for D(, Ri, S), Rb=0
|
|
|
![*](LeafRowHandle.png) |
|
for D(Rb), Ri=0
|
|
|
![collapse V](Expanded.png) |
|
exercise:
|
|
|
![collapse V](Expanded.png) |
|
using the memory and register values from previous exercise, what is the value of following operands:
|
|
|
![collapse V](Expanded.png) |
|
9(%rax, %rdx)
|
|
|
![*](LeafRowHandle.png) |
|
0x11 // 0x9 + 0x100 + 0x3 = address 0x10C
|
|
|
![collapse V](Expanded.png) |
|
260(%rcx, %rdx)
|
|
|
![*](LeafRowHandle.png) |
|
0x13 // 260 = 0x104, 0x104 + 0x1 = 0x3 = address 0x108
|
|
|
![collapse V](Expanded.png) |
|
0xFC( , %rcx, 4)
|
|
|
![*](LeafRowHandle.png) |
|
0xFF // 0xFC + 0x4 * 0x1 = address 0x100
|
|
|
![collapse V](Expanded.png) |
|
(%rax, %rdx, 4)
|
|
|
![*](LeafRowHandle.png) |
|
0x11 // 0x100 + 0x4 * 0x3 = address 0x10C
|
|
|
![collapse V](Expanded.png) |
|
leaq Src, Dest
|
|
|
![*](LeafRowHandle.png) |
|
load effective address
|
|
|
![*](LeafRowHandle.png) |
|
Src is address expression (any of those discussed above)
|
|
|
![*](LeafRowHandle.png) |
|
Dest is a register
|
|
|
![*](LeafRowHandle.png) |
|
sets Dest to address computed by expression
|
|
|
![*](LeafRowHandle.png) |
|
example: leaq (%rdx,%rcx,4), %rax
|
|
|
![collapse V](Expanded.png) |
|
uses:
|
|
|
![collapse V](Expanded.png) |
|
computing address without actually going to memory
|
|
|
![*](LeafRowHandle.png) |
|
e.g., translation of p = &x
|
|
|
![collapse V](Expanded.png) |
|
arithmetic of the form x + k*i
|
|
|
![*](LeafRowHandle.png) |
|
for k = 1, 2, 4, or 8
|
|
|
![collapse V](Expanded.png) |
|
Does leaq go to memory? NO
|
|
|
![*](LeafRowHandle.png) |
|
it just “does the math” to computer an address
|
|
|
![collapse V](Expanded.png) |
|
leaq vs movq example
|
|
|
![collapse V](Expanded.png) |
|
arithmetic
|
|
|
![collapse V](Expanded.png) |
|
unary instructions (take one argument)
|
|
|
![*](LeafRowHandle.png) |
|
incq D: D ← D + 1
|
|
|
![*](LeafRowHandle.png) |
|
decq D: D ← D - 1
|
|
|
![*](LeafRowHandle.png) |
|
negq D: D ← -D
|
|
|
![*](LeafRowHandle.png) |
|
notq D: D ← ~D
|
|
|
![collapse V](Expanded.png) |
|
binary instructions (take two arguments)
|
|
|
![*](LeafRowHandle.png) |
|
addq S,D: D ← D + S
|
|
|
![*](LeafRowHandle.png) |
|
subq S,D: D ← D - S
|
|
|
![*](LeafRowHandle.png) |
|
imulq S,D: D ← D * S
|
|
|
![*](LeafRowHandle.png) |
|
xorq S,D: D ← D ^ S
|
|
|
![*](LeafRowHandle.png) |
|
orq S,D: D ← D | S
|
|
|
![*](LeafRowHandle.png) |
|
andq S,D: D ← D & S
|
|
|
![*](LeafRowHandle.png) |
|
salq k,D: D ← D << k
|
|
|
![*](LeafRowHandle.png) |
|
sarq k,D: D ← D >> k
|
|
|
![collapse V](Expanded.png) |
|
long arith (long x, long y, long z) { long t1 = x+y; long t2 = z+t1; long t3 = x+4; long t4 = y * 48; long t5 = t3 + t4; long rval = t2 * t5; return rval; }
|
|
|
![*](LeafRowHandle.png) |
|
arith: leaq (%rdi,%rsi), %rax addq %rdx, %rax leaq (%rsi,%rsi,2), %rdx salq $4, %rdx leaq 4(%rdi,%rdx), %rcx imulq %rcx, %rax ret
|
|
|
![collapse V](Expanded.png) |
|
exercise:
|
|
|
![*](LeafRowHandle.png) |
|
using the same memory and register values as previous exercises
|
|
|
![collapse V](Expanded.png) |
|
determine the destination and the value that will be stored at that destination for the following instructions
|
|
|
![collapse V](Expanded.png) |
|
addq %rcx, (%rax)
|
|
|
![*](LeafRowHandle.png) |
|
0x100 (0xFF + 0x1) stored at 0x100
|
|
|
![collapse V](Expanded.png) |
|
subq %rdx, 4(%rax)
|
|
|
![*](LeafRowHandle.png) |
|
0xA8 (0xAB - 0x3) stored at 0x104
|
|
|
![collapse V](Expanded.png) |
|
imulq $16, (%rax, %rdx, 4)
|
|
|
![*](LeafRowHandle.png) |
|
0x110 (0x10 * 0x11) stored at 0x10C
|
|
|
![collapse V](Expanded.png) |
|
incq 8(%rax)
|
|
|
![*](LeafRowHandle.png) |
|
0x14 stored at 0x108
|
|
|
![collapse V](Expanded.png) |
|
decq %rcx
|
|
|
![*](LeafRowHandle.png) |
|
0x0 (0x1 - 0x1) stored at %rcx
|
|
|
![collapse V](Expanded.png) |
|
subq %rdx, %rax
|
|
|
![*](LeafRowHandle.png) |
|
0xFD (0x100 - 0x3) stored at %rax
|
|
|