Senast uppdaterad: 971128

Assembler

Register

Register är en form av variabler. Till skilnad från vanliga variablar finns registerna i processorn och inte i minnet.

I Intels första processor 8088 fanns det ett flertal register som t.ex. AX, BX, CX. Registerna var 16 bitar stora d.v.s två byte eller rättare sagt en Word. I alla nyare modeller av Intells processorer finns samma register kvar som i 8088. Detta är bara för att processorna ska vara bakåt kompatibla, d.v.s. de program som är skrivna till en 8088 ska även gå att köra på en Pentium Pro(Om inte Oprativ Systemet hindrar).
Givetvis har vissa ändringar skett, när 386 kom som använde 32-bitar, utvidgades registerna till EAX, EBX, ECX, o.s.v. Dessutom har det lags till fler register.

Alla ni som använder Windows 95 har säkert fått något program att "Utföra en förbjuden åtgärd". Säkert har in också tryckt på "Mer infomation". Då visas bl.a. värdenan på det flesta registerna. Varför denna funktion finns med kan man fråga sig, det är väldigt få som gör windows-program i assembler och inte ens de har glädje av siffrorna.

De allmänna registerna

Till de allmänna registerna hör AX, BX, CX, DX.

AX står för Ackumulator reg.
BX för Base reg. Används vid "minnes indexering"
CX för Count reg. Används ofta som räknare.
DX används ofta till minnesadressering

Registerna är delade i två delar t.ex. AX i AH och AL

        ---------------AX---------------
        0 0 0 0 0 0 0 0  0 0 0 0 0 0 0 0        
        ------AH-------  ------AL-------
Som jag nämnde tidigare är dessa register utvidgade f.o.m. 386 till EAX. Det finns alltså yttligare 16 bitar i registert. Dessvärre går det inte att nå dem på samma sätt som AH och AL.

AL är en "byte" stor vilket medför att den kan lagra tal mellan 0 och 255 ( 2^8 = 256 )
AX är en "word" och kan därmed lagra tal mellan 0 och 65535 ( 2^16 = 65536 )
EAX är en "double word" vilket blir 0 - 4294967295 ( 2^32 = 4294967296 )

 

MOV

Mov är ett av alla kommandon som finns. Det står för engelskans Move och betyder mycket riktigt flytta. Med Mov kan man flytta in värden i registerna.

MOV AX,5     ( Flyttar in 5 i AX )
MOV BL,34    ( Flyttar in 34 i BL )

Man kan även flytta mellan register

MOV AX,BX    ( Flyttar värdet i BX till AX )
Man kan inte flytta värden mellen t.ex. AX och BL eftersom de är olika stora.

Minnet

I IBMs Första PC fanns 1 MB RAM minne ( 1 048 576 bytes ). För att kunna beskriva en possition i minnet krävdes det därmed 20 bitar( 2^20 = 1 048 576) och registernas storlek var bara 16. Microsoft som gjorde det första Oprativ Systemet beslutade att använda två register för att beskriva en possition i minnet. Man delade i minnet i segment med 16 bytes mellanrum, varje segment var 65536 bytes stort.


XXXXXXXX-Segment nr 1-XXXXXXXXXX 
        XXXXXXXX-Segment nr 2-XXXXXXXXXX
                XXXXXXXX-Segment nr 3-XXXXXXXXXX
                        XXXXXXXX-Segment nr 4-XXXXXXXXXX
                                 XXXXXXXX-Segment nr 5-XXXXXXXXXX

Possitionen i segmentet kallas "offset". Possitionen i minnet beskrivs alltså Segment:Offset. Vill man räkna ut platsen tar man "segment*16 + Offset". En plats i minnet kan på det här sättet beskrivas på flera olika sätt. Jag tror BIOS använde 384 kb av minnet i den första "PCn", så det blev bara 640 kb kvar till dos. Bill Gates lär ha sagt att ingen kommer någonsin behöva mer än 640 kb minne , vilket denna man aldrig skulle säga idag ( Win95 kräver i stortsätt 16 mb). Eftersom man velat vara bakåt kompatibel använs samma system fortfarande i dos. Nu mera skrivs mycket i "Portected Mode", vilket ger tillgång till mer minne. Det vi går igenom här är "Real Mode".

Ett första litet program

Låt oss börja med något enkelt som att skriva ut text på skärmen. Programt Skrivs in i en vanlig text beandlare som t.ex. edit eller notepad. Filen sparas med som *.asm . För att göra filen körbar compileras den med en compilator. Själv använder jag Microsoft MASM. Tyvärr fungrar inte följande exempel med TASM som använder andra "startkommandon". För att compilera med Masm skriv : ml fil.asm

.model tiny
.386
.stack
.data
text db "Detta ska skrivas ut$"
.code
.startup
        mov ah,09h		;Flyttar 09h till ah
        lea dx,text		;Flyttar offsetaddressen till text in i DX
        int 21h			;Anropar Dosfunktion.
.exit
end

.model

Talar om för compilatorn vilken minnesmodel vi vill använda. I det här fallet är den allra minsta vald som heter "tiny". När man använder tiny blir progamfilen ändelsen com.

.386

Anger vilket instuktionsuppsättning vi ska använda. Vi skulle lika gärna kunnat välja .286 i det här fallet.

.stack

Fyller ingen funktion i det här programet.

.data

Under denna rubrik deklrerar vi de variablar vi vill ha. I det här exemplet finns en variabel som heter "text". "db" är en förkortning på "define byte". Vill man ha en variabel som är en byte stor skriver man: variabel db 8 variabel får nu utgångvärdet 8. Vill man inte ge variabeln något värde kan man ange "?". Vill man däremot att variabeln ska vara en word stor använder man istället "dw".

.code

Här börjar koden!

.stratup

Ställler in rätt värde i CS, DS och IP (Code- och Data-Segment samt Instuctionspekare).

Int 21h

"Int" anropar en redan färdig funktion. Int 21h anropar dom s.k. dosinterupten. Det finns otaliga dosinterupt och man väljer genom att i AH ange nummret på den funkktion man vill ha. I exemplet ovan används alltså dosinterupt 9h. Detta interupt vill ha offsettaddressen till den sträng man vill skriva ut i DS:DX. (DS ställs in till rätt värde vid .Startup) Vidare skriver den ut från DS:DX tills den hittar ett $-tecken. För att få in offsetadderssen till DX används kommandot LEA.

.exit

Hoppar till baka till dos

end

Här slutar compilatorn att compilera.