Programavimas asembleriu
Darbo su asembleriu pradmenys
Segmento rusys:
Code Segment (CS).
Data Segment (DS).
Stack Segment (SS).
Segmenton registrai:
CS, DS, SS, ES
General Purpose Register - bendri tikslo registrai: AX, BX, CX, DX.
Pvz.:
MOV CX, 00
MOV CH, 00
MOV CL, 00
Pointer Register (rodyklės registras): SP (stack pointer) ir BP (base pointer).
Index Register (indekso registrai): SI (source index) ir DI (destination index).
Instruction Pointer Register (apmokymo rodykles registras): IP (
Fizinis adresas postūmis + 16 * (segmento registras) 141q165b
0010H (postūmis)
(bloko numeris) (segmento registras) 141q165b
(fizinis adresas)
Redaktorius leidzia įvesti ir ruosti savas programas. Galima naudotis DOS redaktorium EDLIN - paeiliui eilutėmis redaguojančiu vartotojo programą. ESM negali tiesiogiai vykdyti redaktoriaus suredaguotą programą. Asembleris ją pakeičia į objektinę (masininių kodų) programą, kurią supranta ESM.
DOS programą gali patalpinti į bet kurią atminties vietą. Tačiau reikia zinoti, kur ji bus patalpinta. Todėl ji, naudojantis uzkrovikliu (Linker) LINK pakeičiama į perkeliamą programą. Tokiu būdu uzkroviklis LINK is objektinio modelio (jį sukuria asembleris) sukuria vykdomajį modulį ir gali sujungti kelis objektinius modulius į vieną perkeliamą modulį.
Sukurtą programą galima iskviesti, surinkus jos vardą kaip DOS komandą. Tai darytina, jei programa yra be klaidų. Tačiau, kol programa nėra suderinta, ją reikia iskviesti naudojantis derintoju DEBUG, leidziančiu tirti programą, pateikti ir keisti kintamųjų reiksmes, sustabdyti programą norimam taske, vykdyti programą pazingsniui, taisyti ją.
Programą sudaro operatoriai, kurie apraso realizuojamas operacijas. Operatoriais gali būti arba komanda arba asemblerio kalbos pseudooperatorius. Pseudooperatoriai nurodo asembleriui, ką reikia veikti su įvedamais daviniais ir komandomis.
Asembleris leidzia įvesti konstantas - dvejatainę (0011 1011B), desimtainę (135D), sesioliktainę (03BFAH), literalinę (simbolių eilutę, kuri paimama į kabutes (") arba apostrofus (') ), neigiamus skaičius (desimtainį = - 32D, dvejetainį ar sesioliktainį, įvestą papildomu kodu).
Kiekviena asemblerio komanda gali turėti iki 4 laukų:
[zymė(label):] Mnemokodas [operandas] [;komentaras]
Būtinas tik mnemokodo laukas, o kvadratiniuose skliaustuose esantys laukai yra nebūtini. Laukai turi būti atskirti bent vienu tarpeliu. Zymė iki 31 simbolio (A - Z, a - z, 0 - 9, pradedant raide, nenaudojant komandų sutrumpinimų). Vietoj tarpo naudoti - "_" (pvz.: GET_COUNT).
Komentarų laukas atskiriamas. Pseudooperatoriai valdo asemblerio darbą. Labiausiai paplitę duomenų pseudooperatoriai:
ASSUME post_reg, seg_vard[, .]
EQU vardas EQU tekstas: vardai priskiria teksto reiksmę.
DB [vardas] DB israiska [, .].
Rezervuoja baitą, priskiria atminties ląstelei pradinę reiksmę.
DW [vardas] DW israiska [, .].
Analogiskai DB elgiasi su zodziais.
PUBLIC PUBLIC identifikatorius [, .].
Padaro anksčiau apibrėztus identifikatorius priimtinais kitiems programos moduliams.
EXTRN EXTRN vardas, tipas [, .].
Nurodo, kad vardas apibrėztas kitame programos modulyje.
INCLUDE INCLUDE failas. Nurodyto failo turinį įraso į iseities programos duotą failą.
SEGMENT seg_vard SEGMENT [tipas]
seg_vard ENDS
Apibrėzia programos segmento ribas. Kiekvienas apibrėzimas SEGMENT turi baigtis operatoriumi ENDS.
PROC vardas PROC [NEAR]
arba
vardas PROCFAR
vardas PROCFAR
.
.
RET
Vardas ENDP
Vardus pateikia operatorių sekai. Seka prasideda operatoriumi PROC ir baigiasi operatoriumi ENDP.
END END [įėjimo tasko zymė]
Pavyzdziai
K EQU 1024 ; priskirti vardą konstantai
TABLE EQU DS : [BP] [SI] ; priskirti vardą adresų kombinacijai
SPEED EQU RATE ; apraso sinonimą
COUNT EQU CX ; registrui priskiria vardą
BU_MAX DB 255 ; maksimali baito vertė be zenklo
BU_MAX DB 127 ; maksimali baito vertė su zenklu
B_TABLE DB 0,0,0,0,0,8,-13 ; baitų lentelė
W_TABLE DB 1025, -33678, 0 ; zodzių lentelė
arba
B_TABLE DB 5DUP (0), 8, -13 ; baitų lentelė
HIGH_TEM DB ? ; rezervuoja vietą kintamajam HIGH_TEMP
MON_SAL DB 12 DUP (?) ; rezervuoja vietą 12 zodzių lentelei
PAGE 25, 100 ; kiekvieno puslapio dydis apribojamas 25 eilutėm ir 100 simbolių kiekvienoje eilutėje
TITLE tekstas nurodo antrastę, kuri turi būti atspausdinta kiekvieno puslapio antroje eilutėje.
SUBILT tekstas - paantrastė, kuri turi būti atspausdinta kiekvieno puslapio trečioje eilutėje.
Operacijos: +, -, *, /, AND, OR, XOR, NOT, EQ, NE, LT, GT, LE, GE ir kt.
B>a: masm_jonas
Reikia nuspausti ENTER po pirmos ir trečios pastabos, kurios pasirodys ekrane. Po to bus atspausdintos programos transliacijos listingą, jei atspausdinsime.
B>type_jonas.lst
Įvedam uzkroviklį tam, kad sukurti perkeliamą programos failą.
B>a:link_jonas
Taisymui:
a: debug jonas.exe
Komandos:
D adresas - pateikti ląstelės adreso turinį.
E adresas - pakeisti adreso turinį.
F adresas L reik [.] - uzpildyti atminties bloką.
G - įvykdyti programą.
Q - iseiti is derinimo į DOS.
R [reg] - pateikti registrų turinius.
T [ ] įvykdyti komandas [nurod.] ir pateikti registrų turinį.
U [ ] retransliuoti (ad) turinį į komandas asemblerio kalba.
Darbo su displėjumi funkcijos
Norint atspausdinti ekrane komentarą,
spausdiname:
KOM1 DB 'Norimas komentaras
LEA DX, KOM1 ; DX - duomenų skaitiklis
MOV AH, 9
INT 21H
LEA 16 reg, 16 atm ; uzkrauna 16 bitų atminties turinį į 16 bitų registrą.
Detaliau susipazinkime su DEBUG programa
DEBUG
D 40:13 [Enter] - atminties dydis
D FE 00:0 [Enter] 7 sk. eilės Nr. Ir kop. Data
D FFFF:05 [Enter] - ROM BIOS data
Programos masininiais kodais įvedimas:
D>DEBUG
E CS:100 B8 23 01 05 25 00 [ Enter]
E CS:106 8B D8 03 DB 8B CB [Enter]
E CS:10C 2B C8 2B CO 90 CB [Enter]
R (registers)
AX 0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0100 NV UP EI PL NZ NA PO NC
13C6:0100 B82301 MOV AX, 0123
-T
AX 0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6
ES=13C6 SS=13C6 CS=13C6 IP=0103 NV UP EI PL NZ NA
13C6:0103 052500 ADD AX, 0025
-T
AX 0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6
ES=13C6 SS=13C6 CS=13C6 IP=0106 NV UP EI PL NZ NA
13C6:0106 8BD8 MOV BX, AX
-T
AX 0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6
ES=13C6 SS=13C6 CS=13C6 IP=0108 NV UP EI PL NZ NA
13C6:0108 03D8 ADD BX, AX
-T
AX 0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6
ES=13C6 SS=13C6 CS=13C6 IP=010A NV UP EI PL NZ NA
13C6:010A 8BCB MOV CX, BX
-T
AX 0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6
ES=13C6 SS=13C6 CS=13C6 IP=010C NV UP EI PL NZ NA
13C6:010C 2BC8 SUB CX, AX
-T
AX 0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6
ES=13C6 SS=13C6 CS=13C6 IP=010E NV UP EI PL NZ NA
13C6:010E 2BC0 SUB AX, AX
-T
AX 0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6
ES=13C6 SS=13C6 CS=13C6 IP=0110 NV UP EI PL NZ NA
13C6:0110 90 NOP
-T
AX 0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6
ES=13C6 SS=13C6 CS=13C6 IP=0111 NV UP EI PL NZ NA
13C6:0111 CB RETF
Trace of Machine Instructions (masininės instrukcijos takelis).
Masininės programos kodo segmento perziūrėjimui:
D CS:100
-Duomenų nustatymas
>DEBUG
E DS:00 23 01 25 00 00 00 [Enter]
E DS:06 2A 2A 2A [Enter]
E CS:100 A1 00 00 03 06 02 00 [Enter]
E CS:107 A3 04 00 CB [Enter]
D DS:0
13C6:0000 23 01 25 00 00 9A 2A 2A-2A F0 F5 02 2C 10 2E 03
13C6:0010 2C 10 BD 02 2C 10 B1 OD-01 03 01 00 02 FF FF FF ,.,.....
13C6:0020 FF FF FF FF FF FF FF FF-FF FF FF FF FF 0F 64 00 .......d.
13C6:0030 61 13 14 00 18 00 C7 13-FF FF FF FF 00 00 00 00 a........
13C6:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .......
13C6:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 .!.......
13C6:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 ...
13C6:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ....
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0100 NV UP EI PL NZ NA
13C6:0100 A10000 MOV AX 0000] DS:0000=0123
-T
AX=0123 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0103 NV UP EI PL NZ NA
13C6:0103 03060200 ADD AX 0002] DS:0002=0025
-T
AX=0148 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=0107 NV UP EI PL NZ NA
13C6:0107 A30400 MOV [0004],AX DS:0004=9A00
-T
AX=0148 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=13C6 ES=13C6 SS=13C6 CS=13C6 IP=010A NV UP EI PL NZ NA
13C6:010A CB RETF
-D DS:0
13C6:0000 23 01 25 00 48 01 2A 2A-2A F0 F5 02 2C 10 2E 03 #.%.H.***.,.
13C6:0010 2C 10 BD 02 2C 10 B1 OD-01 03 01 00 02 FF FF FF ,.,.....
13C6:0020 FF FF FF FF FF FF FF FF-FF FF FF FF FF 0F 64 00 .......d.
13C6:0030 61 13 14 00 18 00 C7 13-FF FF FF FF 00 00 00 00 a........
13C6:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .......
13C6:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 .!.......
13C6:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 ...
13C6:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ....
-Q
Trace of Machine Instructions (masininės instrukcijos takelis).
-Atminties dydzio nustatymas:
E CS:100 CD 12 CB [Enter]
R [Enter]
-A [Asemble] komanda
A 100 [Enter]
MOV AL,25 [Enter] Pasirodzius asemblerio programėlei
MOV BL 2 [Enter] Pabaigiama galima tęsti. Pabaigiam su [Enter]
ADD AL,BL [Enter]
RET
Po to ekrane matomas toks vaizdas:
xxxx:0100 MOV AL,25
xxxx:0102 MOV BL,32
xxxx:0104 ADD AL,BL
xxxx:0106 RET
Dabar DEBUG pasiruosusi priimti kitą instrukciją. Tik spustelėjus Enter klavisą tam, kad dar kartą baigti operaciją.
-U (Unassemble) komanda pateikia asemblerio instrukcijų masininį kodą:
U 100, 106 [Enter]
Uzrasius sia eilutę ekrane bus pateikta:
XXXX:0100 B025 MOV AL, 25
XXXX:0102 B332 MOV BL, 32
XXXX:0104 00D8 ADD AL, AL
XXXX:0106 C3 RET
-R, -T, ir t.t.
W (Write) komanda
Aplinkybės:
- perskaityti programą naudojant debug n: filename [Enter]
Su D perziūrėti, su E redaguoti
Su W [Enter] - issaugoti pakeitimus
DEBUG
A ir E sukuria programą
Įvardinti: N filename.com
Suzinomas programos uzimamų baitų skaičius
Iskviesti R CX registrą [Enter]
DEBUG pateiks CX 0000
Įrasoma programos ilgis baitais
Pataisyta programa įrasoma: W [Enter]
Tikrinant patogu naudoti: R IP [Enter]. Įrasykime į IP 0100 [Enter]. Po to R ir su T patikrinti. Nekeistinos CS, DS, SP ir SS reiksmės
Susipazinkime su DOS DEBUG programa
MASM leis sukurti objektinį kodą ir sąjungą (link) - .exe ar .com vykdytiną kodą:
source filename [.ASM]: nurodyti suredaguotą saltinio programą [Enter]
object filename [ filenamesOB"Ų [Enter
source listing [NUL. LST]: [Enter]
source reference [NUL. CRF]: [Enter]
page 60,132
TITLE . EXASM1 (EXE) Registrų operacijų pavyzdys
STACKSG SEGMENT PARA STACK 'Stack'
DB 12 DUP ('STACKSEG')
STACKSG ENDS
CODESG SEGMENT PARA 'Code'
BEGIN PROC FAR
ASSUME SS:STACKSG,CS:CODESG,DS:NOTHING
PUSH DS
SUB AX, AX
PUSH AX
MOV AX, 012H
ADD AX, 0025H
MOV BX, AX
ADD BX, AX
MOV CX, BX
SUB CX, AX
SUB AX, AX
NOP
RET
BEGIN ENDP
CODESG ENDS
END BEGIN
TITLE ...(EXE) MOV IR ADD operacijos
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
STACKSG SEGMENT PARA STACK 'Stack'
DW 32 DUP (?)
STACKSG ENDS
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DATASG SEGMENT PARA 'Code'
DOFA FLDA DW 250
007D FLDB DW 125
???? FLDC DW ?
BEGIN PROC FAR
ASSUME CS:CODESG, DS:DATASG, SS:STACKSG
PUSH DS
SUB AX, AX
PUSH AX
MOV AX, DATASG ; DATASG adresas
MOV DS, AX ;įrasomas į DS
MOV AX, FLDA
ADD AX, FLDB
MOV FLDC, AX
RET
BEGIN ENDP
CODESG ENDS
END BEGIN
BEGIN PROC FAR
ASSUME CS:CODESG, SS:STACKSG
PUSH DS
SUB AX, AX
PUSH AX
CALL B10
RET
BEGIN ENDP
B10 PROC
CALL C10
RET
B10 ENDP
C10 PROC
RET
C10 ENDP
CODESG ENDS
END BEGIN
TITLE CASE (COM) Change lowercase to uppercase
CODESG SEGMENT PARA 'CODE'
ASSUME CS:CODESG, DS:CODESG, SS:CODESG
ORG 100H
BEGIN: JMP MAIN
TITLEX DB 'Change to uppercase letters'
MAIN PROC NEAR
LEA BX, TITLEX + 1 ; 1-st char to change
MOV CX, 31 ; No. chars to change
B20:
MOV AH, [BX] ; Char from TITLEX
CMP AH, 61H ; Is it
JB B30 ; lower
CMP AH, 7AH ; case
JA B30 ; letter?
AND AH, 11011111B ; Yes - convert
MOV [BX], AH ; Restore in TITLEX
B30:
INC BX ; Set for next char
LOOP B20 ; Loop 31 times
RET
MAIN ENDP
CODESG ENDS
END BEGIN
|