Rekenkundige instruksies Logiese instruksies 8086 INSTRUKSIESTEL Rekenkundige instruksies Logiese instruksies Skuif en roteer instruksies String soek en vergelyk instruksies Tutoriaal 2 : Watcom samesteller kode RS245-2003-Lesing 5
ADD en SUBTRACT [Hoofstuk 5.1] ADD AX,XB; (* AX <= AX+BX *) ADC AX,BX; (* AX <= AX+BX+CF *) Die ADC is nuttig as byvoorbeeld die volgende wil doen: BX AX Wil dus 32 bis getalle hanteer. + DX CX DX CX ADD CX,AX; (* CX <= CX+AX *) ADC DX,BX; (* DX <= DX+BX+CF *) Kyk self na INC RS245-2003-Lesing 5
Let op die verskil tussen SUB en CMP: SUB AX,BX; (* AX <= AX- BX *) CMP AX,BX; (* AX - BX *) Geen resultaat word gestoor nie - slegs die vlaggies word opgedateer as "compare". MOV AL,3AH (* AL = 3AH *) CMP AL,3AH (* AL = 3AH *) (* AL bly onveranderd maar die zero vlaggie word gestel omdat die ongestoorde resultaat gelyk aan zero is. *) Kyk self na SBB en DEC RS245-2003-Lesing 5
MUL BL (* AX <= AL x BL *) MUL BX (* AX, DX <= AX x BX *) MUL [Hoofstuk 5.2] MUL BL (* AX <= AL x BL *) MUL BX (* AX, DX <= AX x BX *) (DX bevat die mees belangrike grepe *) Kyk self na IMUL, DIV en IDIV Ons maak in die kursus relatief min gebruik van bostaande instruksies. RS245-2003-Lesing 5
DAA (Decimal adjust after addition) [Hoofstuk 5.3] Gestel ons wil die desimale getalle 29 en 38 optel. As die getalle in BCD hanteer word: mov al,29H mov bl,38H add al,bl (* al = 61H *) daa (* al = 67H *) daa tel 00H, 06H, 60H of 66H by om die korrekte resultaat te kry. In bostaande geval 61H + 06H = 67H DAA kyk onder andere na die "Auxilliary carry" vlaggie. Die vlaggie dui aan dat daar 'n oordrag was van die laagste 4 bisse na die hoogste vier bisse. Kyk na voorbeeld 5-19 Kyk self na DAS. AAA,AAD,AAM en AAS is van minder belang. RS245-2003-Lesing 5
Logiese instruksies [Hoofstuk 5.4] AND,OR,XOR,TEST,NOT,NEG AND en OR is reeds bekend. XOR doen 'n eksklusiewe of tussen die bisse van twee binêre getalle. Dit is handig as sekere bisse wil negeer: gestel al =10101010 bl =00001111 xor al,bl (* al = 10100101 *) Wat is die resultaat van: XOR AL,AL ? NOT keer al die bisse om en NEG gee die twee's komplemente getal. RS245-2003-Lesing 5
TEST TEST is dieselfde as AND behalwe dat die resultaat nie bewaar word nie - slegs die vlaggies word opdateer. Dit is handig as jy wil bepaal of 'n sekere bis 'n '1' is sonder om die register se inhoud te verander. MOV AL,71H (* AL=01110001 *) TEST AL,02H (* AL=01110001 *) (* 02H = 00000010 daarom is die (ongestoorde) resultaat = zero en die zero vlaggie = 1. Die zero vlaggie sê dus vir ons in hierdie geval dat die tweede minsbelangrike bis van AL 'n '0' is. *) RS245-2003-Lesing 5
SHIFT EN ROTATE [Hoofstuk 5.5] NB Let op die verskil tusssen SHR en SAR. AL CF SHR AL,1 Die bisse word almal een posisie na regs geskuif en 'n nul word ingeskuif. MOV AL,7AH (* AL =01111010 *) SHR AL,1 (* AL =00111101 *) RS245-2003-Lesing 5
Die mees belangrike bis bly behoue. AL CF SAR AL,1 Die mees belangrike bis bly behoue. Voorbeeld: MOV AL,82H; (* AL = 10000010 (- 126 desimaal) *) SAR AL,1 (* AL = 11000001 (- 63 desimaal ) *) 2 's komplement: 10000010 => 01111101 + 1 = 01111110 negatiewe getal neem dus die komplement. = (-) 126 Of anders beskou: -27 + 2 = -128+2 = -126 Kyk self na SHL, RCL,ROL,RCR,ROR RS245-2003-Lesing 5
Die inhoud van AL bly onveranderd. SCASB [Hoofstuk 5.6] Die zero-vlaggie word gestel indien AL-ES:[DI] gelyk is aan zero. DI word outomaties opgedateer. Die inhoud van AL bly onveranderd. Die instruksie kan gebruik word om 'n greep in geheue te soek: CLD MOV AL,41H; (* ASCII karakter 'A' *) MOV CX,1000H; (* Gaan 'n maksimum van 1000H grepe ondersoek *) MOV DI,2000H; (* begin soek by ES:2000H *) REPNE SCASB; (* as ons eindig met die zero vlaggie = '1' dan weet ons 'n greep gelyk aan 41H is gevind. Die posisie kan bepaal word uit die waarde in CX *) Kyk self na CMPS RS245-2003-Lesing 5
Gedeeltelike samesteller kode soos deur Watcom kompileerder gegenereer Tutoriaal2.C Gedeeltelike samesteller kode soos deur Watcom kompileerder gegenereer IN DIE DATASEGMENT L$16: 0000 48 61 6C 6C 6F 21 00 ; Hallo! IN DIE KODESEGMENT Gestel sp = 0x30 mov bp,sp ; bp=0x30 sub sp,0x0014 ; sp=0x1c maak plek vir tydelike data L$1: mov ax,ss mov es,ax ;es segment nou gelyk aan ss segment lea di,-0x10[bp] ;di = 0x30-0x10 = 0x20 mov si,offset DGROUP:L$16 ;si wys na H van Hallo! movsw ;"Ha" na stapel [0x20] en [0x21] (Tydelike data area) movsw ;"ll" na stapel [0x22] en [0x23] movsw ;"o!" na stapel [0x24] en [0x25] movsb ; 0 na stapel [0x26] RS245-2003-Lesing 5
stapel 0x1a 0x18 0x16 0x14 ;bp=0x30, sp=0x1c mov al,-0xa[bp] ; 0 in al [0x30-0xa = 0x26] xor ah,ah ; 0 in ah push ax ; 00 na stapel [0x1a en 0x1b] mov al,-0xb[bp] ; "!" na al [0x30-0x0b =0x25] push ax ; "!" en 0 na stapel [0x18 en 0x19] mov al,-0xc[bp] ; "o" na al [0x30-0x0c=0x24] push ax ; "o" en 0 na stapel [0x16 en 0x17] mov al,-0xd[bp] ; "l" na al [0x30-0x0d=0x23] mov cx,ax ; "l" in cl en 0 in ch mov al,-0xe[bp] ; "l" in al [0x30-0x0e=0x22] mov bx,ax ; "l" in bl en 0 in bh mov al,-0xf[bp] ; "a" in al [0x30-0x0f=0x21] mov dx,ax ; "a" in dl en 0 in dh mov al,-0x10[bp] ; "H" in al [0x30-0x10=0x20] call Karakterstoor_ ; IP na stapel [0x14 en 0x15] stapel 0x22 "l" 0x20 "H" "a" 0x1E 0x1C 0x1a 0x18 "!" 0x16 "o" 0x14 IP RS245-2003-Lesing 5
Hierdie is 'n 12 krediet-uur vak. U moet ongeveer Karakterstoor_: push bp mov bp,sp ;bp = 0x12 push di ;sp= 0x10 .... mov al,[bp+4] ; "o" ..... 0x22 "l" 0x20 "H" "a" 0x1E 0x1C 0x1a 0x18 "!" 0x16 "o" 0x14 IP 0x12 bp 0x10 di Ons sou ook mov al,[sp+6] kon gebruik, maar sp is nie 'n geldige adresregister nie. Die voordeel van bp is dat jy nie verder hoef boek te hou van die aantal pushes nie. Dit is morsig om die data af te "pop" om dit in die hande te kry. Dit rede sal duideliker wees as ons by onderbrekings kom. Notas: Hierdie is 'n 12 krediet-uur vak. U moet ongeveer 12 uur per week aan die vak spandeer. RS245-2003-Lesing 5