Les 3: Gegevenstransfers + adresseermodes To understand a program, you must become both the machine and the program. - A. Perlis ca3-1 Overzicht • • • • • Inleiding Registers Adresexpressies Gegevenstransfer Adresseermodes ca3-2 Von Neumann-machine Fysiek zicht BUS adres data controle CVE Controle klok cache registers Geheugen Invoer/Uitvoer ca3-3 Het geheugen • Array van geheugencellen of BAU-cellen (basic addressable units) • Elke BAU-cel heeft een adres n bit 0 1 2 3 4 bau-cel 0 bau-cel 1 bau-cel 2 bau-cel 3 bau-cel 4 ... ca3-4 Het geheugen • Typische BAU-cel groottes: bit, byte, woord • Bewerkingen op het geheugen: - lezen - schrijven ca3-5 Bewerkingen op geheugen adres lezen data CVE adres schrijven data geheugen ca3-6 Voorstelling van het geheugen 8 0 1 2 3 4 5 6 7 16 0 2 4 6 8 10 12 14 32 0 4 8 12 16 20 24 28 ca3-7 Overzicht • • • • • Inleiding Registers Adresexpressies Gegevenstransfer Adresseermodes ca3-8 Von Neumann-machine Fysiek zicht BUS adres data controle CVE Controle controle klok cache registers Geheugen Geheugen:bau-cellen RAM Invoer/Uitvoer ca3-9 IA32 registerverzameling 32 EAX EBX ECX EDX ESI EDI EBP ESP EIP EFLAGS accumulator basis counter data source index destination index basispointer stack pointer instruction pointer flags Registerverzameling: IA32 ca3-10 IA32 registerverzameling EAX EBX ECX EDX ESI EDI EBP ESP EIP EFLAGS 32 AHAXAL BHBXBL CHCXCL DHDXDL SI DI BP SP IP FLAGS ca3-11 Intel 64 registerverzameling RAX EAX AX AL RBX EBX BX BL RCX ECX CX CL RDX EDX DX DL RDI EDI DI DIL RSI ESI SI SIL RBP EBP BP BPL RSP ESP SP SPL R8 R8D R8W R8L R9 R9D R9W R9L R15D R15W R15L R15 (2004) … Registerverzameling: intel 64 ca3-12 IA32 segmentregisters 16 gs fs ss es ds cs ca3-13 EFLAGS T S Z A P C zero sign trap interrupt direction overflow i/o level nested task auxiliary carry pariteit carry I NT IO O D ca3-14 IA32 Vlottende-komma/MMX registers 80 64 ST0 MMX0 ST1 MMX1 ST2 MMX2 ST3 MMX3 ST4 MMX4 ST5 MMX5 ST6 MMX6 ST7 MMX7 Registers: mmx ca3-15 IA32 XMM registers 128 128 XMM0 XMM8 XMM1 XMM9 XMM2 XMM10 XMM3 XMM11 XMM4 XMM12 XMM5 XMM13 XMM6 XMM14 XMM7 XMM15 IA32 X86-64 ca3-16 AVX registers 2015 2011 ca3-17 Alpha registerverzameling 64 r0 64 ... ... r31 PC ... ... 0000000000000000000000000000000000000000 f0 0000000000000000000000000000000000000000 Registerverzameling: alpha f31 ca3-18 Itanium registerverzameling • 128 registers voor algemeen gebruik (64 bit) [r0..r127] • 128 registers voor vlottendekommagetallen (82 bit) [f0..f127] (goed voor double extended floating point formaat) • 64 predikaatregisters (1 bit) [p0..p63] • 8 sprongregisters (64 bit) [b0..b7] • Instructiewijzer (64 bit) Registerverzameling: itanium ca3-19 Overzicht • • • • • Inleiding Registers Adresexpressies Gegevenstransfer Adresseermodes ca3-20 Absoluut adres n 0 Absoluut adres = Effectief adres waarde ca3-21 Verschuiving n 0 Basisadres offset Effectief adres waarde effectief adres = basisadres + offset ca3-22 Indirect adres n 0 Primair adres Effectief adres Secun. adres waarde effectief adres = mem[primair adres] ca3-23 Adresexpressie Beschouw het geheugen als een array van bytes 0 1 2 3 4 5 6 7 8 9 10 11 12 01 20 12 03 A3 F7 93 23 F2 AA 92 19 33 ... mem16[2] mem8[11] mem32[5] ca3-24 Adresexpressie Beschouw alle registers als een array ax bx cx ip sp r1 r2 r3 r4 reg[bx] reg[ip] reg[r2] ca3-25 Voorbeeld typedef struct r { int a[5]; char b[5]; struct { int d, e; } c; struct r *n; } linklist; a[0] a[1] a[2] a[3] … a[4] b[0]..b[4] c.d c.e n ca3-26 Berekening van offsets a[0] a[1] a[2] a[3] a[4] b[0]..b[4] c.d c.e n (2*4) 8 bytes (5*4) 20 bytes (5*4 + 5*1) 25 bytes (5*4 + 5*1 + 4 + 4) 33 bytes ca3-27 r a[0] Berekening van offsets a[1] a[2] a[3] a[4] b[0]..b[4] c.d c.e n adresexpressie adres van r r adres van r.a[1] r+4 adres van r.b[0] r+20 adres van r.c.d r+25 adres van r.n r+33 waarde van r.b[0] mem8[r+20] waarde van r.c.d mem32[r+25] ca3-28 a[0] a[1] a[2] a[3] a[4] b[0]..b[4] c.d c.e n a[0] a[1] a[2] a[3] a[4] b[0]..b[4] c.d c.e n … Dangling pointers! r Berekening van offsets adresexpressie adres van r.a[1] r+4 adres van r.n r+33 adres van r.n->a[1] mem32[r+33]+4 ca3-29 a[0] i a[1] a[2] a[3] a[4] b[0]..b[4] c.d c.e n adres van i adresexpressie i (b.v. 1100) waarde van i mem32[i] (b.v. 3) adres van r.a[i] r+mem32[i]*4 waarde van r.a[i] mem32[r+mem32[i]*4] 1100 3 out-of-bounds error! r Berekening van offsets ←i ca3-30 Het geheugen • Bitnummering • Bytenummering • Alignatie ca3-31 Bitnummering Neerwaarts genummerd bitpatroon lengte n n-1 n-2 ... 3210 Opwaarts genummerd bitpatroon lengte n 0123 ... n-2 n-1 ca3-32 Bitnummering n n+1 n+2 n+3 n+4 n+5 n+6 n+7 n+8 n+9 01 ... 30 31 opwaarts Voordeel: consistent met byte adressering 31 30 ... 10 neerwaarts Voordeel: consistent met bitgewicht ca3-33 Bytenummering: Big Endian n n+1 n+2 n+3 n+4 n+5 n+6 n+7 n+8 n+9 MSB LSB 32-bit gegeven ca3-34 Bytenummering: Little Endian n n+1 n+2 n+3 n+4 n+5 n+6 n+7 n+8 n+9 MSB LSB 32-bit gegeven ca3-35 Voorbeeld Geheugen 16 ... 78 9C 6B A2 28 18 10 00 19 A2 67 ... Big endian: 100016 = 409610 Little endian: 001016 = 1610 ca3-36 Alignatie Gealigneerd 4n 2n n 2n n Niet-gealigneerd 4n ca3-37 r Berekening van offsets Niet-gealigneerd a[0] a[1] a[2] a[3] a[4] b[0]..b[4] c.d c.e n Gealigneerd a[0] a[1] typedef struct r { int a[5]; struct { int d, e; } c; struct r *n; char b[5]; } linklist; a[2] a[3] a[4] b[0]..b[4] c.d c.e n Gat in de geheugenlayout (padding) ca3-38 Overzicht • • • • • Inleiding Registers Adresexpressies Gegevenstransfer Adresseermodes ca3-39 Gegevenstransfer doel bron breedte geheugen registers randapparaat geheugen registers randapparaat ca3-40 Gegevenstransfer: mov 32 mov doel, bron voorbeelden mov eax, ebx Instructie:mov 00 04 08 0C 10 00B00300 00004000 00004000 00330020 0003300A …. mov ebx, [4] eax 00920000 00000010 mov [8], ebx ebx 00000010 00004000 mov ecx, 64h ecx 03000440 00000064 Alle waarden zijn hexadecimaal! ca3-41 Load/store ld r, bron reg[r] = mem[bron] st r, doel mem[doel] = reg[r] Load/store architectuur ca3-42 Verwisselen van twee waarden: xchg xchg doel, bron temp = doel doel = bron bron = temp Instructie:xchg ca3-43 Little endian big endian bswap R Instructie:bswap ca3-44 Bewaren en herstellen van registers mov mov mov mov …. mov mov mov mov [10h], eax [14h], ebx [18h], ecx [1ch], edx eax, [10h] ebx, [14h] ecx, [18h] edx, [1ch] mov mov mov mov mov …. mov mov mov mov ebp,10h [ebp], eax [ebp+4], ebx [ebp+8], ecx [ebp+0ch], edx eax, [ebp] ebx, [ebp+4] ecx, [ebp+8] edx, [ebp+0ch] ca3-45 Werking van een stapel: push & pop 32 mov eax, 10h push eax pop ebx push bron esp esp Instructie:push 1200 1204 1208 120C 1210 …. 00B00300 00000010 00004000 00330020 0003300A eax 00920000 00000010 ebx 00004000 00000010 pop doel Instructie:pop esp 00001208 0000120C Alle waarden zijn hexadecimaal! ca3-46 Bewaren en herstellen van registers op de stapel push push push push …. pop pop pop pop eax ebx ecx edx edx ecx ebx eax esp edx esp ecx esp ebx esp eax esp ca3-47 pushad & popad pushad Instructie:pushad push van eax, ecx, edx, ebx, (oude esp), ebp, esi, edi popad Instructie:popad pop van edi, esi, ebp, -, ebx, edx, ecx, eax esp edi esi ebp oude esp ebx edx ecx eax ca3-48 Lengte-aanduidingen mov [192900h], ax lengte = 2 bytes mov [192900h], 9 lengte = ? - mov byte ptr [192900h], 9 lengte = 1 bytes - mov word ptr [192900h], 9 lengte = 2 bytes - mov dword ptr [192900h], 9 lengte = 4 bytes ca3-49 Input/Output: IA32 in al, port reg[al] = io[port] in ax, port reg[ax] = io[port] in eax, port reg[eax] = io[port] out port,al io[port] = reg[al] out port,ax io[port] = reg[ax] out port,eax io[port] = reg[eax] Instructie:in Instructie:out ca3-50 Operaties op toestandregister lahf reg[ah] = reg[status] sahf reg[status] = reg[ah] pushfd reg[esp] = reg[esp] - 4 mem32[reg[esp]] = reg[status] popfd reg[status] = mem32[reg[esp]] reg[esp] = reg[esp] + 4 Instructie:lahf Instructie:sahf Instructie:pushfd Instructie:popfd ca3-51 Overzicht • • • • • Inleiding Registers Adresexpressies Gegevenstransfer Adresseermodes ca3-52 Adresseermodes • • • • • • • • • Absolute adressering Indexering Basisadressering Basis+indexering Geheugenindirect Registerindirect Postincrement, predecrement Letterlijk Segmentering ca3-53 Absolute adressering mov eax, [20] reg[eax] = mem32[20] mov [20], al mem8[20] = reg[al] Adresseermode:absoluut goed voor scalaire veranderlijken met een vast adres int g; main() { g = 10; mov dword ptr [19290h],10 } mov g, 10 ca3-54 Indexering mov eax, [20+edi*2] mov [200+si], al reg[eax] = mem32[20+reg[edi]*2] mem8[200+reg[si]] = reg[al] int g[5]; main() { adres edi int i; offset for (i=0; i<5; i++) g[i] = i; mov [19290h+edi*4],edi } (geschaalde) index Adresseermode:indexering ca3-55 Array-indexering a: array [1..9] of integer; 32 100 104 108 10c 110 114 118 11c 120 124 128 12c Adres van a[i] ? a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 108h+(reg[ebx]-1)*4 = 104h+reg[ebx]*4 mov eax, [104h+ebx*4] Alle waarden zijn hexadecimaal! ca3-56 Adresseermode: basis Basisadressering mov eax, [ebx+20] typedef struct { int a, b; } record; record rec; ebx ebx main() { record *r=&rec; } r->a = 10; r->b = 11; reg[eax] = mem32[reg[ebx]+20] a b adres offset mov dword ptr [ebx+0],10 mov dword ptr [ebx+4],11 ca3-57 Adresseermode: basis+index Basis+indexering mov eax, [ebx+20+edi*4] reg[eax] = mem32[ reg[ebx]+20+reg[edi]*4] typedef struct { ebx a int a, b[5]; b[0] } record; adres b[1] esi b[2] record rec; b[3] offset ebx b[4] main() { record *r=&rec; int i = 2; r->b[i] = 15; mov dword ptr [ebx+4+esi*4],15 } ca3-58 Geheugenindirectie rec1 edi typedef struct r { int a; struct r *n; } record; rec2 NULL record rec1, rec2; mem32[mem32[reg[edi]+4]+4] = 0 main() { record *r = &rec1; r->n = &rec2; r->n->n = NULL; } mov edi, 192900h mov dword ptr [edi+4],192908h mov esi,[edi+4] mov dword ptr [esi+4],0 Adresseermode: geheugenindirect mov dword ptr [[edi+4]+4],0 ca3-59 Geheugenindirectie Motorola 680x0 processor ([An,disp,Xn*Scale],Odisp) An disp scale Xn + x + primair adres adreslocatie Odisp operandlocatie + operand ca3-60 Registerindirectie int i; edi main() { int *j = &i; *j = 99; mov dword ptr [edi],99 mem32[reg[edi]] = 99 } edi 99 ←i Adresseermode: registerindirect ca3-61 Postincrement Adresseermode: postincrement Predecrement Adresseermode: predecrement int i[5]; main() { int *j=&(i[0]); *j++ = 99; } edi mem32[reg[edi]] = 99 reg[edi] = reg[edi]+4 mov dword ptr [edi],99 add edi,4 680x0 move.l (a1)+,d3 move.l –(a1),d3 680x0 move.l d0,-(a0) ; push move.l (a0)+,d0 ; pop edi i[0] i[1] i[2] i[3] i[4] ca3-62 Instructie: string stosb stosw stosd lodsb lodsw lodsd movsb movsw movsd String-operaties mem8[reg[edi]] = reg[al]; reg[edi] ±= 1 mem16[reg[edi]] = reg[ax]; reg[edi] ± = 2 mem32[reg[edi]] = reg[eax]; reg[edi] ± = 4 reg[al] = mem8[reg[esi]]; reg[esi] ± = 1 reg[ax] = mem16[reg[esi]]; reg[esi] ± = 2 reg[eax] = mem32[reg[esi]]; reg[esi] ± = 4 mem8[reg[edi]] = mem8[reg[esi]]; reg[esi] ± = 1; reg[edi] ± = 1 mem16[reg[edi]] = mem16[reg[esi]]; cld + reg[esi] ± = 2; reg[edi] ± = 2 mem32[reg[edi]] = mem32[reg[esi]]; std reg[esi] ± = 4; reg[edi] ± = 4 ca3-63 Kopiëren van een blok mov ecx,500 cld rep movsb reg[ecx] = 500 d=0 mem8[reg[edi]] =mem8[reg[esi]] reg[edi] = reg[edi] +1 reg[esi] = reg[esi] +1 reg[ecx] = reg[ecx] -1 herhaal totdat reg[ecx] == 0 ca3-64 Letterlijke operand main() { int g; edi g = 99; mov edi,99 reg[edi] = 99 } mov eax,16 mov eax,10h Adresseermode: letterlijk mov eax, 0aah ca3-65 32/64 bit constanten lui $s0,0x1020 $s0 = 10200000 addi $s0,$s0,0x3940 $s0 = 10203940 lui $s0,0x1020 $s0 = 10200000 lw $t0,0x3940($s0) adres = 10203940 [MIPS architectuur] ca3-66 32/64 bit constanten 64 r1 ld r3,-48(r1) ld r2,24(r1) ca3-67 Adresseermode:segmentering Segmentregisters Segmentering gs RAM effectief adres fs ss es ds cs Rechten Limit Basis Segmentdescriptors + lineair adres ca3-68 Adresseermodes IA32 eax eax ebx ebx ecx ecx 1 edx edx 2 edi +( edi esi esi ebp ebp x 4 8 esp basis 8-bit )+ 16-bit 32-bit lea eax,[ebx+esi*4+100] index constante ca3-69 Pauze ca3-70