L'assembly
Eccoci qua, dopo un sacco di teoria iniziamo il vero lavoro.Ovviamente non vi posso insegnare l'intero assembly, però almeno una piccola introduzione ve la darò. Sarete voi che dovrete interessarvi, altrimenti non ce la farete mai.Comunque per farvi qualche idea di come funziona l'assembly, iniziamo pure.
La prima cosa da capire, forse la più importante, sono i registers.Ci sono tre diverse grandezze di registers, quelli a 8, 16 e 32-bit.Iniziamo con i "General Purpose Registers", quelli che userete di più.Sono quattro,
ax,bx,cx,dx.Questi sono registers a 16 -bit, che però possono essere divisi in un high e low byte, ciascuno con un valore di 8-bit.Prendiamo come esempio ax, che può essere usato con un high byte,ah, oppure con un low byte,al.Così si ottengono in tutto tre diversi registers che potrete infatti trattare come se fossero tutti diversi.Poi ci sono gli Index Registers,
si,di,ip e sono registers a 16-bit.Esistono anche Segment Registers,cs,ds,es,ss e infine i Stack Registers,bp e sp.Per arrivare ad un indirizzo di 20-bit, si usa una specie di overlap del
ds e si.DS contiene il segment mentre SI contiene l'offset.I segment registers sapete già quali sono, mentre i registers dell'offset sono:bx,di,si,bp,sp,ip.Lo stack: E' una piccola area di memoria dove potete salvare e ripristinare valori.I commandi che si usano sono
push e pop.Ora, per mandare dati in un register, si usa il commando
mov.Vi faccio un esempio.Se voglio mettere il valore 10 in ax, userò questo commando : mov ax,10La prima cosa dopo il mov sarà la "destinazione", la seconda "l'origine".Nel nostro caso la destinazione è il register ax, l'origine il valore 10 che vogliamo mettere in ax.
Ritorniamo allo stack:Quando farete un programma in assembly, spesso avrete bisogno di più di quella decina di commandi che avete a disposizione.Per questo si possono salvare valori nello stack e , in un secondo tempo, ripristinarli quando ne avrete bisogno.Per portare un valore nello stack, come già detto, si usa il commando
pop,per ripristinare un valore, push.Il concetto che dovete capire, è che non potete salvare e ripristinare come lo volete voi, ma potete ripristinare sempre solamente l'ultimo valore che avete salvato.Un esempio:Push cx
"pusherà" cx nello stackPush ax
"pusherà" ax nello stackPop cx
"popperà" il primo valore dallo stack in cxPop ax
"popperà" il prossimo valore dallo stack in axPerò a causa di quel concetto, i valori cx e ax saranno scambiati.Per questo si usa il commando
xchg.Nel nostro caso basterebbe un xchg ax,cx per rimettere le cose come dovrebbero stare.Dovete però sempre stare attenti a non mettere troppi dati nello stack, altrimenti rischierete lo "stack overflow".Adesso vi farò vedere una lista generale degli opcodes.Cercate di procuravela da qualche parte, forse la includerò nella prossima edizione, così vedrete un pò i commandi che esistono.
AAA - Ascii Adjust for Addition
AAD - Ascii Adjust for Division
AAM - Ascii Adjust for Multiplication
AAS - Ascii Adjust for Subtraction
ADC - Add With Carry
ADD - Arithmetic Addition
AND - Logical And
ARPL - Adjusted Requested Privilege Level of Selector (286+ PM)
BOUND - Array Index Bound Check (80188+)
BSF - Bit Scan Forward (386+)
BSR - Bit Scan Reverse (386+)
BSWAP - Byte Swap (486+)
BT - Bit Test (386+)
BTC - Bit Test with Compliment (386+)
BTR - Bit Test with Reset (386+)
BTS - Bit Test and Set (386+)
CALL - Procedure Call
CBW - Convert Byte to Word
CDQ - Convert Double to Quad (386+)
CLC - Clear Carry
CLD - Clear Direction Flag
CLI - Clear Interrupt Flag (disable)
CLTS - Clear Task Switched Flag (286+ privileged)
CMC - Complement Carry Flag
CMP - Compare
CMPS - Compare String (Byte, Word or Doubleword)
CMPXCHG - Compare and Exchange
CWD - Convert Word to Doubleword
CWDE - Convert Word to Extended Doubleword (386+)
DAA - Decimal Adjust for Addition
DAS - Decimal Adjust for Subtraction
DEC - Decrement
DIV - Divide
ENTER - Make Stack Frame (80188+)
ESC - Escape
HLT - Halt CPU
IDIV - Signed Integer Division
IMUL - Signed Multiply
IN - Input Byte or Word From Port
INC - Increment
INS - Input String from Port (80188+)
INT - Interrupt
INTO - Interrupt on Overflow
INVD - Invalidate Cache (486+)
INVLPG - Invalidate Translation Look-Aside Buffer Entry (486+)
IRET/IRETD - Interrupt Return
Jxx - Jump Instructions Table
JCXZ/JECXZ - Jump if Register (E)CX is Zero
JMP - Unconditional Jump
LAHF - Load Register AH From Flags
LAR - Load Access Rights (286+ protected)
LDS - Load Pointer Using DS
LEA - Load Effective Address
LEAVE - Restore Stack for Procedure Exit (80188+)
LES - Load Pointer Using ES
LFS - Load Pointer Using FS (386+)
LGDT - Load Global Descriptor Table (286+ privileged)
LIDT - Load Interrupt Descriptor Table (286+ privileged)
LGS - Load Pointer Using GS (386+)
LLDT - Load Local Descriptor Table (286+ privileged)
LMSW - Load Machine Status Word (286+ privileged
LOCK - Lock Bus
LODS - Load String (Byte, Word or Double)
LOOP - Decrement CX and Loop if CX Not Zero
LOOPE/LOOPZ - Loop While Equal / Loop While Zero
LOOPNZ/LOOPNE - Loop While Not Zero / Loop While Not Equal
LSL - Load Segment Limit (286+ protected)
LSS - Load Pointer Using SS (386+)
LTR - Load Task Register (286+ privileged)
MOV - Move Byte or Word
MOVS - Move String (Byte or Word)
MOVSX - Move with Sign Extend (386+)
MOVZX - Move with Zero Extend (386+)
MUL - Unsigned Multiply
NEG - Two's Complement Negation
NOP - No Operation (90h)
NOT - One's Compliment Negation (Logical NOT)
OR - Inclusive Logical OR
OUT - Output Data to Port
OUTS - Output String to Port (80188+)
POP - Pop Word off Stack
POPA/POPAD - Pop All Registers onto Stack (80188+)
POPF/POPFD - Pop Flags off Stack
PUSH - Push Word onto Stack
PUSHA/PUSHAD - Push All Registers onto Stack (80188+)
PUSHF/PUSHFD - Push Flags onto Stack
RCL - Rotate Through Carry Left
RCR - Rotate Through Carry Right
REP - Repeat String Operation
REPE/REPZ - Repeat Equal / Repeat Zero
REPNE/REPNZ - Repeat Not Equal / Repeat Not Zero
RET/RETF - Return From Procedure
ROL - Rotate Left
ROR - Rotate Right
SAHF - Store AH Register into FLAGS
SAL/SHL - Shift Arithmetic Left / Shift Logical Left
SAR - Shift Arithmetic Right
SBB - Subtract with Borrow/Carry
SCAS - Scan String (Byte, Word or Doubleword)
SETAE/SETNB - Set if Above or Equal / Set if Not Below (386+)
SETB/SETNAE - Set if Below / Set if Not Above or Equal (386+)
SETBE/SETNA - Set if Below or Equal / Set if Not Above (386+)
SETE/SETZ - Set if Equal / Set if Zero (386+)
SETNE/SETNZ - Set if Not Equal / Set if Not Zero (386+)
SETL/SETNGE - Set if Less / Set if Not Greater or Equal (386+)
SETGE/SETNL - Set if Greater or Equal / Set if Not Less (386+)
SETLE/SETNG - Set if Less or Equal / Set if Not greater or Equal (386+)
SETG/SETNLE - Set if Greater / Set if Not Less or Equal (386+)
SETS - Set if Signed (386+)
SETNS - Set if Not Signed (386+)
SETC - Set if Carry (386+)
SETNC - Set if Not Carry (386+)
SETO - Set if Overflow (386+)
SETNO - Set if Not Overflow (386+)
SETP/SETPE - Set if Parity / Set if Parity Even (386+)
SETNP/SETPO - Set if No Parity / Set if Parity Odd (386+)
SGDT - Store Global Descriptor Table (286+ privileged)
SIDT - Store Interrupt Descriptor Table (286+ privileged)
SHL - Shift Logical Left
SHR - Shift Logical Right
SHLD/SHRD - Double Precision Shift (386+)
SLDT - Store Local Descriptor Table (286+ privileged)
SMSW - Store Machine Status Word (286+ privileged)
STC - Set Carry
STD - Set Direction Flag
STI - Set Interrupt Flag (Enable Interrupts)
STOS - Store String (Byte, Word or Doubleword)
STR - Store Task Register (286+ privileged)
SUB - Subtract
TEST - Test For Bit Pattern
VERR - Verify Read (286+ protected)
VERW - Verify Write (286+ protected)
WAIT/FWAIT - Event Wait
WBINVD - Write-Back and Invalidate Cache (486+)
XCHG - Exchange
XLAT/XLATB - Translate
XOR - Exclusive OR
Ma non pensate che sia tutto qua, per esempio per il commando Jump,
jmp, esistono un sacco di altri commandi, visto che per ogni tipo di condizione occorre un altro commando.Ecco le funzioni del jump :Mnemonic Meaning Jump Condition
JA Jump if Above CF=0 and ZF=0
JAE Jump if Above or Equal CF=0
JB Jump if Below CF=1
JBE Jump if Below or Equal CF=1 or ZF=1
JC Jump if Carry CF=1
JCXZ Jump if CX Zero CX=0
JE Jump if Equal ZF=1
JG Jump if Greater (signed) ZF=0 and SF=OF
JGE Jump if Greater or Equal (signed) SF=OF
JL Jump if Less (signed) SF != OF
JLE Jump if Less or Equal (signed) ZF=1 or SF != OF
JMP Unconditional Jump unconditional
JNA Jump if Not Above CF=1 or ZF=1
JNAE Jump if Not Above or Equal CF=1
JNB Jump if Not Below CF=0
JNBE Jump if Not Below or Equal CF=0 and ZF=0
JNC Jump if Not Carry CF=0
JNE Jump if Not Equal ZF=0
JNG Jump if Not Greater (signed) ZF=1 or SF != OF
JNGE Jump if Not Greater or Equal (signed) SF != OF
JNL Jump if Not Less (signed) SF=OF
JNLE Jump if Not Less or Equal (signed) ZF=0 and SF=OF
JNO Jump if Not Overflow (signed) OF=0
JNP Jump if No Parity PF=0
JNS Jump if Not Signed (signed) SF=0
JNZ Jump if Not Zero ZF=0
JO Jump if Overflow (signed) OF=1
JP Jump if Parity PF=1
JPE Jump if Parity Even PF=1
JPO Jump if Parity Odd PF=0
JS Jump if Signed (signed) SF=1
JZ Jump if Zero ZF=1
Per questo è molto importante avere una lista completa sempre a disposizione.La lista degli opcodes viene fornita da Intel è specialmente all'inizio può essere un grande aiuto.
Visto che stiamo parlando di liste, un'altra lista, indispensabile per ogni programmatore, è la lista degli interrupt.La più nota e completa è la "Ralf Brown's Interrupt list", la troverete sicuramente in Internet.Questa però non la pubblicherò, perchè la lista completa occupa qualche mega di spazio.Quindi dovrete vedere voi un pò in giro, ma non dovrebbe essere un problema.Vi ricordo che avrete assolutamente bisogno di questa lista, prima o poi, quindi cercatela.
Questo è un piccolo riassunto, fatto da Bent Lynggaard, degli 256 interrupts.
INT 00 - CPU-generated - DIVIDE ERROR
INT 01 - CPU-generated - SINGLE STEP; (80386+) - DEBUGGING EXCEPTIONS
INT 02 - external hardware - NON-MASKABLE INTERRUPT
INT 03 - CPU-generated - BREAKPOINT
INT 04 - CPU-generated - INTO DETECTED OVERFLOW
INT 05 - PRINT SCREEN; CPU-generated (80186+) - BOUND RANGE EXCEEDED
INT 06 - CPU-generated (80286+) - INVALID OPCODE
INT 07 - CPU-generated (80286+) - PROCESSOR EXTENSION NOT AVAILABLE
INT 08 - IRQ0 - SYSTEM TIMER; CPU-generated (80286+)
INT 09 - IRQ1 - KEYBOARD DATA READY; CPU-generated (80286,80386)
INT 0A - IRQ2 - LPT2/EGA,VGA/IRQ9; CPU-generated (80286+)
INT 0B - IRQ3 - SERIAL COMMUNICATIONS (COM2); CPU-generated (80286+)
INT 0C - IRQ4 - SERIAL COMMUNICATIONS (COM1); CPU-generated (80286+)
INT 0D - IRQ5 - FIXED DISK/LPT2/reserved; CPU-generated (80286+)
INT 0E - IRQ6 - DISKETTE CONTROLLER; CPU-generated (80386+)
INT 0F - IRQ7 - PARALLEL PRINTER
INT 10 - VIDEO; CPU-generated (80286+)
INT 11 - BIOS - GET EQUIPMENT LIST; CPU-generated (80486+)
INT 12 - BIOS - GET MEMORY SIZE
INT 13 - DISK
INT 14 - SERIAL
INT 15 - CASSETTE
INT 16 - KEYBOARD
INT 17 - PRINTER
INT 18 - DISKLESS BOOT HOOK (START CASSETTE BASIC)
INT 19 - SYSTEM - BOOTSTRAP LOADER
INT 1A - TIME
INT 1B - KEYBOARD - CONTROL-BREAK HANDLER
INT 1C - TIME - SYSTEM TIMER TICK
INT 1D - SYSTEM DATA - VIDEO PARAMETER TABLES
INT 1E - SYSTEM DATA - DISKETTE PARAMETERS
INT 1F - SYSTEM DATA - 8x8 GRAPHICS FONT
INT 20 - DOS 1+ - TERMINATE PROGRAM
INT 21 - DOS 1+ - Function Calls
INT 22 - DOS 1+ - PROGRAM TERMINATION ADDRESS
INT 23 - DOS 1+ - CONTROL-C/CONTROL-BREAK HANDLER
INT 24 - DOS 1+ - CRITICAL ERROR HANDLER
INT 25 - DOS 1+ - ABSOLUTE DISK READ
INT 26 - DOS 1+ - ABSOLUTE DISK WRITE
INT 27 - DOS 1+ - TERMINATE AND STAY RESIDENT
INT 28 - DOS 2+ - DOS IDLE INTERRUPT
INT 29 - DOS 2+ - FAST CONSOLE OUTPUT
INT 2A - NETBIOS
INT 2B - DOS 2+ - RESERVED
INT 2C - DOS 2+ - RESERVED
INT 2D - DOS 2+ - RESERVED
INT 2E - DOS 2+ - PASS COMMAND TO COMMAND INTERPRETER FOR EXECUTION
INT 2F - Multiplex
INT 30 - (NOT A VECTOR!) - DOS 1+ - FAR JMP instruction
INT 31 - overwritten by CP/M jump instruction in INT 30
INT 32 - (no special use)
INT 33 - MS MOUSE
INT 34 - FLOATING POINT EMULATION - OPCODE D8h
INT 35 - FLOATING POINT EMULATION - OPCODE D9h
INT 36 - FLOATING POINT EMULATION - OPCODE DAh
INT 37 - FLOATING POINT EMULATION - OPCODE DBh
INT 38 - FLOATING POINT EMULATION - OPCODE DCh
INT 39 - FLOATING POINT EMULATION - OPCODE DDh
INT 3A - FLOATING POINT EMULATION - OPCODE DEh
INT 3B - FLOATING POINT EMULATION - OPCODE DFh
INT 3C - FLOATING POINT EMULATION - SEGMENT OVERRIDE
INT 3D - FLOATING POINT EMULATION - STANDALONE FWAIT
INT 3E - FLOATING POINT EMULATION - Borland "SHORTCUT" CALL
INT 3F - Overlay manager interrupt (Microsoft/Borland)
INT 40 - DISKETTE - RELOCATED ROM BIOS DISKETTE HANDLER
INT 41 - SYSTEM DATA - HARD DISK 0 PARAMETER TABLE; CPU - MS Windows
INT 42 - VIDEO - RELOCATED DEFAULT INT 10 VIDEO SERVICES (EGA,VGA)
INT 43 - VIDEO DATA - CHARACTER TABLE (EGA,MCGA,VGA)
INT 44 - VIDEO DATA - CHARACTER FONT (PCjr); Novell NetWare
INT 45 - Z100/Acorn
INT 46 - SYSTEM DATA - HARD DISK 1 DRIVE PARAMETER TABLE
INT 47 - Z100/Acorn/Western Digital/SQL Base
INT 48 - KEYBOARD (PCjr) - Z100/Watstar/Acorn/Western Digital/Compaq
INT 49 - SYSTEM DATA (PCjr) - Z100/TI/Watstar/Acorn/MAGic
INT 4A - SYSTEM - USER ALARM HANDLER
INT 4B - IBM SCSI interface; Virtual DMA Specification (VDS)
INT 4C - Z100/Acorn/TI
INT 4D - Z100
INT 4E - TI/Z100
INT 4F - Common Access Method SCSI
INT 50 - IRQ0 relocated by software
INT 51 - IRQ1 relocated by software
INT 52 - IRQ2 relocated by software
INT 53 - IRQ3 relocated by software
INT 54 - IRQ4 relocated by software
INT 55 - IRQ5 relocated by software
INT 56 - IRQ6 relocated by software
INT 57 - IRQ7 relocated by software
INT 58 - IRQ8/0 relocated by software
INT 59 - IRQ9/1 relocated by software; GSS Computer Graphics Interface
INT 5A - IRQ10/2 relocated by software
INT 5B - IRQ11/3 relocated by software; Network
INT 5C - IRQ12/4 relocated by software; Network Interface
INT 5D - IRQ13/5 relocated by software
INT 5E - IRQ14/6 relocated by software
INT 5F - IRQ15/7 relocated by software; HP 95LX GRAPHICS PRIMITIVES
INT 60 - reserved for user interrupt; multiple purposes
INT 61 - reserved for user interrupt; multiple purposes
INT 62 - reserved for user interrupt; multiple purposes
INT 63 - reserved for user interrupt; multiple purposes
INT 64 - reserved for user interrupt; multiple purposes
INT 65 - reserved for user interrupt; multiple purposes
INT 66 - reserved for user interrupt; multiple purposes
INT 67 - reserved for user interrupt; LIM EMS; multiple purposes
INT 68 - multiple purposes
INT 69 - multiple purposes
INT 6A - multiple purposes
INT 6B - multiple purposes
INT 6C - CONVERTIBLE; DOS 3.2; DECnet DOS network scheduler
INT 6D - VGA - internal
INT 6E - DECnet DOS - DECnet NETWORK PROCESS API
INT 6F - Novell NetWare; 10NET; MS Windows 3.0
INT 70 - IRQ8 - CMOS REAL-TIME CLOCK
INT 71 - IRQ9 - REDIRECTED TO INT 0A BY BIOS
INT 72 - IRQ10 - RESERVED
INT 73 - IRQ11 - RESERVED
INT 74 - IRQ12 - POINTING DEVICE (PS)
INT 75 - IRQ13 - MATH COPROCESSOR EXCEPTION (AT and up)
INT 76 - IRQ14 - HARD DISK CONTROLLER (AT and later)
INT 77 - IRQ15 - RESERVED (AT,PS); POWER CONSERVATION (Compaq)
INT 78 - DOS extenders; multiple purposes
INT 79 - multiple purposes
INT 7A - Novell NetWare; IBM 3270; multiple purposes
INT 7B - multiple purposes
INT 7C - multiple purposes
INT 7D - multiple purposes
INT 7E - RESERVED FOR DIP, Ltd. ROM LIBRARY; multiple purposes
INT 7F - multiple purposes
INT 80 - reserved for BASIC; multiple purposes
INT 81 - reserved for BASIC
INT 82 - reserved for BASIC
INT 83 - reserved for BASIC
INT 84 - reserved for BASIC
INT 85 - reserved for BASIC
INT 86 - IBM ROM BASIC - used while in interpreter; multiple purposes
INT 87 - IBM ROM BASIC - used while in interpreter
INT 88 - IBM ROM BASIC - used while in interpreter; multiple purposes
INT 89 - IBM ROM BASIC - used while in interpreter
INT 8A - IBM ROM BASIC - used while in interpreter
INT 8B - IBM ROM BASIC - used while in interpreter
INT 8C - IBM ROM BASIC - used while in interpreter
INT 8D - IBM ROM BASIC - used while in interpreter
INT 8E - INT EE = IBM ROM BASIC - used while in interpreter
INT EF - BASIC - ORIGINAL INT 09 VECTOR
INT F0 - BASICA.COM, GWBASIC, compiled BASIC - ORIGINAL INT 08 VECTOR
INT F1 - reserved for user interrupt
INT F2 - reserved for user interrupt
INT F3 - reserved for user interrupt
INT F4 - reserved for user interrupt
INT F5 - reserved for user interrupt
INT F6 - reserved for user interrupt
INT F7 - reserved for user interrupt
INT F8 - reserved for user interrupt
INT F9 - reserved for user interrupt
INT FA - reserved for user interrupt
INT FB - reserved for user interrupt
INT FC - reserved for user interrupt
INT FD - reserved for user interrupt
INT FE - AT/XT286/PS50+ - destroyed by return from protected mode
INT FF - AT/XT286/PS50+ - destroyed by return from protected mode
Ora ritorniamo alla nostra programmazione.Prendiamo un semplice esempio, un file che visualizza un testo sullo schermo.
.model small
.stack
.data
messaggio db "Assembly e' facile$"
.code
mov dx, offset messaggio
mov ax, seg messaggio
mov ds, ax
mov ah,9
int 21h
mov ax,4c00h
int 21h
end
Questo codice lo dovete salvare in un formato "nomefile".asm .Poi copiatelo nella directory dove si trova il Turbo Assembler (TASM) è digitate : Tasm "nomefile".asm
e, se non vi viene segnalato nessun errore (non dovrebbe succedere), continuate con Tlink "nomefile" (di solito l'estensione sarà .obj).Così avete creato un file eseguibile.Fatelo partire e vedrete apparire il testo "Assembly e' facile".
Ma esaminiamo attentamente il codice:
.model small :
Model small indica che tutto il codice è stato messo in un unico segment.Anche il data segment è stato messo in un unico segment.Poi esistono ancora il model
tiny, significa che tutto il codice e il data si trovano in un unico segment.Il model compact,in questo caso tutti gli elementi del codice sono in un unico segment, però ogni porzione del data può essere messa in un segment.Poi esistono il model medium, large e flat,che però per ora non ci interessano.Messaggio db "Assembly e' facile$" : Questo è il messaggio che verrà visualizzato.Messaggio,in questo caso è il label, cioè il nome al quale il programma fa riferimento nel codice.db significa declare byte.il byte(che sarà in ASCII),può essere "dichiarato" in bytes, db, words,dw, e double word,dd.
Troverete spesso anche un "?" alla fine di una dichiarazione, tipo
esempio db ?Ciò significa che il data non è inizializzato, che non ha valora con il quale inziare.
Ci possiamo mettere anche :
Esempio1 db 0
Esempio2 dw 1
Così quando il programma caricherà,
esempio1 sarà uguale a 0,e esempio2 sarà uguale a 1.Anche qua vi dovete rendere conto che c'e' una cosa importante da rispettare.Se dichiarate qualcosa come word, non potete mettere il valore di esso in un register di 8 bit e non potete neanche mettere il valore di una dichiarazione di un byte in un register di 16-bit.Un esempio:Mov al, Esempio1
Nessun problemaMov ax, Esempio1
Non potete farlo!Mov bx, Esempio2
Va beneMov bl, Esempio2
Impossibile!Infine troviamo il nostro testo che deve essere visualizzato
"Assembly e' facile$".Il testo dovrà essere messo sempre tra " ..." e alla fine del vostro messaggio dovrete mettere un $.Questo significa per l'assembler che la riga è finita.Ora riprendiamo il nostro piccolo programma come esempio.Lo scopo nel programmare in assembly e, specialmente quando programmate virus, è quello di rendere il codice più corto possibile, visto che in questo modo il virus avrà la grandezza di KB più piccola.Ci sono molti piccoli esempi, tipo
Mov bx,ax
Xchg bx,ax
Il primo commando occuperà 2 bytes, il secondo invece solo 1...questo solo per dimostrarvi che potete facilmente rimpicciolire il vostro codice usando dei commandi diversi.Nel nostro caso potete scambiare
Mov dx, offset messaggio
Mov ax, seg messaggio
Mov ds, ax
Con un semplice
Mov dx, offset messaggio
Inserendo il seguente commando all'inizio del codice:
Mov ax,@data
Mov ds,ax
Tutto questo perchè tutto il data nel segment ha lo stesso valore del
seg. Mettendo tutto quanto in ds non lo dovremo ricaricare ogni volta che vogliamo usare un'altra cosa nello stesso segment.Il commando per visualizzare il testo è
mov ah,9.L'int 21h eseguirà il commando e con mov ax,4c00hInt 21h
Ritorneremo al Dos.Alla fine ci dovrete mettere solamente un "end".
Questo è tutto per la lezione di oggi, rileggetevi tutto con calma, rimediate quelle cose di cui vi ho detto...e non fatevi scappare la prossima edizione.