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,10

La 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 stack

Push ax "pusherà" ax nello stack

Pop cx "popperà" il primo valore dallo stack in cx

Pop ax "popperà" il prossimo valore dallo stack in ax

Però 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 problema

Mov ax, Esempio1 Non potete farlo!

Mov bx, Esempio2 Va bene

Mov 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,4c00h

Int 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.

 

INDICE