Contacts

Introduction to the assembler language. Special situations of the V86 mode

Assemblers MASM, TASM and WASM differ in each other. However, the creation of simple programs for them practically does not have differences, with the exception of the assembly and layout itself.

So, our first program for MASM, TASM and WASM, which displays the English letter "A" in the current cursor position, that is, in the left upper corner Screen:

Model Tiny .code Org 100h Start: MOV AH, 2 MOV DL, 41H INT 21H INT 20H END START This text can be typed in any simple text editor - For example, in NotePad from Windows (but not in Word and not in another "tricky"). However, I recommend the "advanced" text editor with a syntax illumination, for example, PSPAD (see section). Then save this file with extension.asm, for example, in the MyProg folder. Let's call the ATEST file. So, we got: C: \\ MyProg \\ ATEST.ASM.

NOTE
Please note that in the first team we recorded 2 instead of 02h. MASM, TASM and WASM, like EMU8086, admit such "liberty". Although you can write 02h - there will be no errors.

Explanation of the program:

.Model Tiny - 1st line. Directive.Model defines a memory model for a specific file type. In our case, this is a file with COM extension, so we select the TINY model, in which the segments of the code, data, and stack are combined. The TINY model is designed to create Som type files.

.code. - 2nd line. This directive begins the code segment.

Org 100h. - 3rd string. This command sets the value of the software counter in 100h, because when loading the Som file in memory, DOS selects the first 256 bytes to the PSP data block for the first 256 bytes (decimal number 256 equal to hexadecimal 100h). The program code is located only after this block. All programs that are compiled into COM files must begin with this directive.

start: Mov Ah, 02h - 4th line. Start label is located in front of the first command in the program and will be used in the END directive to specify which command begins the program. MOV instruction places the value of the second operand in the first operand. That is, the value of 02h is placed in the EN register. What is it done for? 02H is a DOSOVA function that displays a symbol on the screen. We write a program for DOS, so we use the commands of this operating system (OS). And we write this feature (or rather its number) it is in the EN register, because the interrupt 21H uses this particular register.

MOV DL, 41H - 5th line. The symbol code "A" is entered into the DL register. The code "A" code according to the ASCII standard is the number 41h.

INT 21H. - 6th line. This is the most interruption of 21H - a command that causes the DOS system function specified in the EN register (in our example is a 02h function). The INT 21H command is the main means of interaction of programs from the OS.

INT 20H. - 7th line. This interrupt that reports the operating system about the output from the program and the transfer of management console application. In the event that the program is already compiled and running from OS, the INT 20H command will return us to OS (for example, in DOS).

End Start. - 8th line. The END directive completes the program at the same time indicating which label should be executed.

INT 3.

Call interrupt 3 (#bp, stop point)

8086

iNT 3.

CD iB.

Int. iMM8.

Challenge interrupts iMM8.

8086

iNT 13.

Into

Call interrupt 4 (#OF, overflow) if eflags.of \u003d 1

8086

into

Description:

Team INT 3. It is intended to generate interrupt 3 and to describe the operation identical to the INT N command except that the interrupt number here is not present directly in the operation code, but implicitly set equal to 3.

This interruption is intended for use by the debugger, which places a special single-tone command. INT 3. (CCCH code) instead of the first command byte or instead of single-way commands.

There is a second way to call for this interrupt using a two-byte code INT 3 (CD03H code). but this method In practice, it does not apply, all X86 assemblers are default by default mnemonics INT 3. As a single-tone command with CCH code (but this does not exclude the possibility of manual programming of a two-byte). In addition to the size of the code, the processing process of single and two-byte commands is different. INT 3.. The interrupt generated by a single-man command in EV86 mode (CR4.VME \u003d 1) is not exposed to redirecting the interrupt redirection card (as described for mode 2, mode 3, mode 5) and is always processed by the protected mode handler through the descriptor in the IDT table. In addition, in V86 mode, the IOPL field checks are not checked for this interrupt and, accordingly, the error cannot be generated #gp error when eflags.iopl< 3, то есть однобайтная команда не является IOPL-чувствительной .

Operation:

The algorithm presented here describes not only the processor behavior when executing the command INT 3. External interruption or generation of a special situation.

Then Goto. Real-Address-Mode;

If (eflags.vm \u003d 1 and eflags.iopl< 3 AND

(CR4.VME \u003d 0 or CR4.VME \u003d 1 AND IRB [N] \u003d 1)

) (* IrB [n] - bit, corresponding to interrupt N in the map of redirection of interrupts *)

#GP (0); (Software interrupt INT N in mode: (1) V86 at eflags.iopl< 3, (2) EV86 Режим 2 *)

ELSE. (* Protected mode or V86 / EV86 * mode)

If (eflags.vm \u003d 1 and cr4.vme \u003d 1 and

(Int n) and irb [n] \u003d 0)

ELSE Goto. Protected-Mode.; (* Hardware Interrupts, Special Situations; Int N Software Interrupts: (1) Protected Mode, (2) V86 with EFLAGS.IOPL \u003d 3, (3) EV86 Mode 1 or 4 *)

Real-Addres-Mode:

If ((interrupt number * 4) + 3 goes beyond the segment when accessing the IVT interrupt vectors table) then #gp; Fi;

If (there is no place for 6 bytes in the stack) then #ss; Fi;

Eflags.if \u003d 0; (* Reset the flag of interrupts *)

Eflags.tf \u003d 0; (* Reset Flag Traps *)

Eflags.ac \u003d 0; (* Reset the flag of the alignment control mode *)

CS \u003d IVT [Interrupt number * 4] .Selector;

Eip \u003d IVT [Interrupt number * 4]. FFFSET and 0X0000FFFFH;

(* Continuation of work in real addressing ... *)

EV86-MODE: (* CR0.PE \u003d 1, EFLAGS.VM \u003d 1, CR4.VME \u003d 1, EV86 mode is an int n program interrupt, with IRB [N] \u003d 0 - mode 3 or mode 5 *)

If (in the V86 task stack there is no space for 6 bytes) THEN #SS (0); Fi;

tempflags \u003d Flags;

tempflags.nt \u003d 0;

Then eflags.if \u003d 0; (* Reset the flag of the permission of interrupts *)

tempflags.if \u003d eflags.vif;

Eflags.vif \u003d 0; (* Resetting the virtual flag of interrupts *)

Eflags.tf \u003d 0; (* Reset Flag Traps *)

Push (Tempflags);

(* Error codes are not entered on the stack *)

CS \u003d IVT_V86 [Interrupt number * 4] .Selector; (* Table of interrupt vectors IVT_V86 is located at the beginning of the address space of the task V86 *)

EIP \u003d IVT_V86 [Interrupt number * 4] .Offset and 0x0000FFFFH; (* Older 16-bit EIP register are reset *)

(* Continuing work in EV86 ... *)

PROTECTED-MODE: (* Cr0.pe \u003d 1, hardware interrupts, special situations; Int N software interrupts in mode: (1) Protected mode, (2) V86 with eflags.iopl \u003d 3, (3) EV86 Mode 1 or mode 4 *)

If ((interrupt number * 8) + 7 does not fall within the IDT) TAN #GP (interrupt number * 8 + 2 + ext); Fi;

(* Hereinafter, in the error code parameters, the term +2 means setting the error code of the error code, and the terms + ext - means setting the EXT error code in accordance with whether the error has caused the interrupt program EXT \u003d 0 or external EXT \u003d 1 * )

AR descriptor byte must set the interrupt gateway, a trap gateway or a task gateway, otherwise #gp (interrupt number * 8 + 2 + EXT);

If (software interrupt or special situation) (* Those. One of the cases int n, int 3, int01, bound or into *)

If (CPL\u003e DPL Gateway)

#GP (interrupt number * 8 + 2); (* CR0.PE \u003d 1, DPL gateway< CPL, программное прерывание *)

The gateway must be present, otherwise #NP (interrupt number * 8 + 2 + EXT);

If (Gateway Tasks)

Then Goto. Task-Gate.;

Goto. Trap-or-int-gate; (* CR0.PE \u003d 1, interrupt or trap gateway *)

Trap or-int-Gate: (* Protected mode or V86 / EV86 mode, trap or interrupt gateway *)

Checking the new CS selector specified in the gateway descriptor, and the appropriate descriptor from LDT or GDT:

The selector must be not zero, otherwise, #gp (EXT);

The selector index should fall within the descriptors table, otherwise #gp (selector + EXT);

The selected handle must be a segment descriptor code, otherwise #gp (selector + EXT);

The segment must be present (p \u003d 1), otherwise #NP (selector + EXT);

If (uncoordinated code segment) and (code segment dpl< CPL)

If eflags.vm \u003d 0

Then Goto. Int-to-inter-priv; (* Cr0.pe \u003d 1, eflags.vm \u003d 0, interrupt or trap gateway, inconsistent code segment, dpl code segment< CPL *)

ELSE (* EFLAGS.VM \u003d 1 *)

If (DPL of the new code segment ≠ 0) Then #Gp (selector code segment + ext); Fi;

Goto. INT-FROM-V86-MODE;(* Cr0.pe \u003d 1, eflags.vm \u003d 1, interrupt or trap gateway, dpl code segment \u003d 0, CPL \u003d 3 *)

ELSE. (* CR0.PE \u003d 1, interrupt or trap gateway, consistent code segment or inconsistent code segment with DPL \u003d CPL *)

If eflags.vm \u003d 1 Then #gp (code segment selector + ext); Fi;

If ((Corresponding Corresponding) OR (code segment dpl \u003d CPL))

Then Goto. Int-to-intra-priv; (* Cr0.pe \u003d 1, interrupt or trap gateway, DPL code segment ≤ CPL for a consistent segment, code segment DPL \u003d CPL for inconsistent segment *)

ELSE #GP (code segment selector + ext); (* DPL\u003e CPL for a consistent segment or DPL ≠ CPL for inconsistent segment *)

Int-to-inter-priv: (* Protected mode, interrupt or trap gateway, inconsistent code segment, DPL code segment< CPL *)

If (current TSS 32-bit)

TSSStackAddress \u003d (New Code Segment DPL * 8) + 4

If ((TSSStackAddress + 5)\u003e TSS limit) (* (TSSstackAddress + 7)\u003e

NEWSS \u003d [TSS + TSSStackADDress + 4] base; (* 2 bytes loaded *)

(* 4 bytes loaded *)

ELSE. (* Current TSS 16-bit *)

TSSStackAddress \u003d (New Code Segment DPL * 4) + 2

If ((TSSStackAddress + 3)\u003e TSS limit) (* (TSSStackAddress + 4)\u003e TSS limit - for some processor models *)

Then #ts (selector of the current TSS + EXT);

NEWESP \u003d [TSS + TSSStackAddress base]; (* 2 bytes loaded *)

NEWSS \u003d [TSS + TSSStackAddress + 2 base]; (* 2 bytes loaded *)

The RPL selector must be equal to the DPL of the new code segment, otherwise #ts (SS selector + EXT);

The DPL of the stack segment must be equal to the DPL of the new code segment, otherwise #ts (SS selector + EXT);

If (32-bit gateway)

Then new stack should take place for 20 bytes (24 bytes, if there is an error code), otherwise #ss (ext)

ELSE The new stack should take place for 10 bytes (12 bytes, if there is an error code), otherwise #ss (EXT)

SS: ESP \u003d TSS (NEWSS: NEWESP); (* Download new SS and ESP values \u200b\u200bfrom TSS *)

If (32-bit gateway)

Then.

ELSE CS: IP \u003d GATE (Selector: Offset);

Download SS descriptor in the hidden part of the SS register;

If (32-bit gateway)

Push (long pointer to the old stack - SS: ESP);

Push (long pointer to return point - CS: EIP); (* 3 words are complemented to 4 *)

Push (error code);

Push (long pointer to the old stack - SS: SP); (* 2 words *)

Push (long pointer to return point - CS: IP); (* 2 words *)

Push (error code);

CPL \u003d DPL of the new code segment;

If (interrupt gateway) then eflags.if \u003d 0 fi; (* Reset the interrupt flag *)

Eflags.rf \u003d 0;

(* Continuation of work in protected mode at a level with large privileges ... *)

Int-from-v86-mode: (* V86 / EV86 mode, interrupt or trap gateway, DPL \u003d 0, CPL \u003d 3 *)

(* Current TSS is always 32-bit in mode V86 *)

If (TSS limit< 9) (* TSS Limit< 11 - для некоторых моделей процессоров *)

Then #ts (selector of the current TSS + EXT);

NEWSS \u003d [Base TSS + 8]; (* 2 bytes loaded *)

NEWESP \u003d [Base TSS + 4]; (* 4 bytes loaded *)

Check the selector of the new stack segment of the NEWSS and the appropriate descriptor from LDT or GDT:

The selector must not be zero, otherwise #ts (EXT);

The selector index should fall within the descriptor table, otherwise the #ts (SS selector + EXT);

The RPL selector should be zero, otherwise #ts (SS selector + EXT);

The DPL of the stack segment must be zero, otherwise the #ts (SS selector + EXT);

The descriptor must have a data descriptor descriptor format allowed for recording (W \u003d 1), otherwise #ts (SS selector + EXT);

The segment must be present (p \u003d 1), otherwise #ss (ss selector + ext);

If (32-bit gateway)

The new stack should take place for 36 bytes (40 bytes, if there is an error code), otherwise #ss (EXT)

The new indicator of the instruction should fall within the new code segment, otherwise #gp (EXT); (* The instruction pointer is determined by the offset field value from the gateway descriptor *)

Tempeflags \u003d eflags;

Eflags.vm \u003d 0; (* The processor comes out of the V86 mode to process interrupt in protected mode *)

If (interrupt gateway)

Then eflags.if \u003d 0;

CPL \u003d 0; (* Switch to zero privilege level *)

SS: ESP \u003d TSS (NEWSS: NEWESP); (* Download SS0 and ESP0 values \u200b\u200bfrom TSS *)

Push (GS);

Push (FS); (* Expands to two words *)

Push (DS); (* Expands to two words *)

Push (ES); (* Expands to two words *)

Gs \u003d 0; (* Segment registers are reset. It is unacceptable to subsequent use of zero selectors in secure mode *)

PUSH (temps); (* Expands to two words *)

Push (Tempeflags);

Push (CS); (* Expands to two words *)

Push (error code); (* If present, 4 bytes *)

CS: EIP \u003d Gate (Selector: Offset); (* Download selector: offset from the 32-bit gateway descriptor *)

ELSE (* 16-bit gateway *)

The new stack must take place for 18 bytes (20 bytes, if there is an error code), otherwise #ss (EXT)

(* Saving in a stack of 16-bit registers occurs similarly to a 32-bit gateway *)

(* Return from the interrupt with the IRET command back to the V86 mode from the 16-bit segment will not be possible, since the VM flag will not be saved in the stack and will not be recovered from the image of EFLAGS when returning *)

(* Continuation of work in protected mode at the zero level of privileges ... *)

Int-to-intra-priv: (* CR0.PE \u003d 1, DPL \u003d CPL or consistent segment with DPL ≤ CPL *)

If (32-bit gateway)

Then new stack should take place for 12 bytes (16 bytes, if there is an error code), otherwise #ss (EXT)

ELSE The new stack should take place for 6 bytes (8 bytes, if there is an error code), otherwise #ss (EXT)

The new indicator of the instruction should fall within the new code segment, otherwise #gp (EXT);

If (32-bit gateway)

Push (long pointer to return point); (* 3 words are complemented to 4 *)

CS: EIP \u003d Gate (Selector: Offset); (* Download selector: offset from the 32-bit gateway descriptor *)

Push (error code); (* If present, 4 bytes *)

Push (long pointer to return point); (* 2 words *)

CS: IP \u003d Gate (Selector: Offset); (* Download selector: offset from the 16-bit gateway descriptor *)

Push (error code); (* If present, 2 bytes *)

Download CS descriptor in the hidden part of the CS register;

If (interrupt gateway) then eflags.if \u003d 0; Fi;

(* Continuation of work in protected mode without changing the privilege level ... *)

Task-Gate: (* CR0.PE \u003d 1, Task gateway *)

Check TSS selector from Task Gateway Description:

The selector must set GDT (bit Ti \u003d 0), otherwise #gp (TSS selector + EXT);

The selector index should fall within the GDT table, otherwise #gp (TSS selector + EXT);

Checking the corresponding TSS descriptor corresponding to the selected selector:

The TSS descriptor must have a type of free TSS (type.b \u003d 0), otherwise #gp (TSS selector + EXT);

TSS must be present (p \u003d 1), otherwise #NP (TSS selector + EXT);

Switch-Tasks (with attachment) in TSS; (* Here "with the attachment" means the fact that when initializing the context of a new task will be set by the eflags.nt \u003d 1 flag, and the TSS selector (old) task will be copied in the TSS segment (old) segment - see Addressing and Multitasking: Means Multisascia Support *)

If (interrupt is a special situation with error code)

The stack must be a place for error code, otherwise #ss (EXT);

Push (error code);

The EIP instruction pointer should fall within the CS segment, otherwise #gp (EXT);

(* Loading the context of a new task is accompanied by additional checks as described in the section Addressing and Multitasking: Multisadality Support Means *)

(* Continuation of work in the context of a new task ... *)

Special situations of protected regime:

INT 3.But also upon receipt of any external interruption or generation of a special situation. Bit EXT. In the error code of the external interrupt).

  • descriptor vector (index) of interrupts is not within the Table of Interrupt Descriptors (IDT);
  • descriptor vector (index) of the interrupt, is not a trap gateway descriptor, an interrupt gateway or a task gateway;
  • there is a software interruption or a software special situation (that is, one of the cases: int n, int 3, int01, bound or into) and at the same time current privilege level (CPL) tasks more privilege levels(DPL) gateway Descriptor From the IDT table -
  • segment selector in the appropriate processed vector (index) of interrupting the trap gateway descriptor, the interrupt gateway or the task gateway is a zero selector;
  • the selection of the segment segment of the trap gateway or the interrupt gateway descriptor does not fall within the corresponding table of descriptors;
  • tSS selector index from the corresponding interruption of the task gateway descriptor does not fall within global Descriptor Table (GDT);
  • descriptor The new code segment is not a code segment descriptor;
  • (DPL) new coordinated code segment current level privilege (CPL) Tasks -
  • level of privileges descriptor (DPL) of the new inconsistent code segment is not equal current privilege level (CPL) Tasks -
  • tSS selector from the corresponding interruption of the task gateway descriptor indicates local table descriptors (LDT);
  • the TSS descriptor of the new task is noted as busy- Type.b ≠ 1.
  • the address on which the new value should be read for stack pointer (SS: ESP), goes beyond the TSS segment;
  • the selection of the new stack segment is a zero selector;
  • the selector index of the new stack segment does not fall within the corresponding table of descriptors;
  • the requested level of privileges (RPL) The selection of the new stack segment is not equal (DPL) new code segment -
  • level of privileges descriptor (DPL) of the new stack segment is not equal level of privileges descriptor (DPL) new code segment -
  • the new stack segment is not a data segment available for recording -
  • the corresponding interrupt the trap gateway descriptor, the interrupt gateway, the task gateway or the TSS descriptor is marked as unaccompanied (Bit P descriptor is reset);
  • the new code segment is not present (bit P. The segment descriptor is reset).
  • when writing to the stack (including in a new stack, if the stack switching) values addresses Return, stack pointer, flags or error code is suitable for the permissible border of the stack segment;
  • the new stack segment is not present (bit P segment descriptor is reset).

Special situations of real addressing regime:

The list of special situations presented here characterizes the processor behavior not only when executing the command INT 3.But also upon receipt of any external interruption or generation of a special situation.

Special situations of the V86 mode:

The list of special situations presented here characterizes the processor behavior not only when executing the command INT 3.But also upon receipt of any external interruption or generation of a special situation. Bit EXT. In the error code, it is used to indicate external with respect to the interrupted event program (

All DOS functions are called by interrupting 21H (in decimal notation 33). The first version of DOS contained 42 functions. In the second, 33 more functions are added to them, which are stored in all subsequent versions. The choice of a specific function is carried out by recording the corresponding number to the AH register.

Function 02: Output single symbol on screen

To output one character on the PC screen used

21H Interrupt Function 02:

mOV DL,<код выводимого символа>

The output symbol is highlighted in the cursor position (whatever it is recorded), after which the cursor moves to one position to the right. If the cursor was at the end of the screen string, then it moves to the beginning of the next line, and if the cursor was at the end of the last line of the screen, the screen contents shifts one line upwards, and the empty string appears at the bottom, and the cursor is installed.

Symbols with codes 7, 8, 9, 10 (0ah) and 13 (0HDH) are performed in a special way. Symbol with code 7 (bell, call) on the screen is not highlighted (and the cursor does not shift), and causes sound signal. Symbol with code 8 (Backspase, step back) Returns the cursor to one position to the left, unless it was in the left line of the string. The symbol with code 9 (TAB, tab) displaces the cursor to the right to the nearest position, multiple 8. The symbol with code 10 (Line feed, line translating) moves the cursor to the next line string, leaving it in the same column. Symbol with code 13 (Carrige Returne, the carriage return) sets the cursor to the beginning of the current line; Conclusion in a row of characters with codes 13 and 10 means translating a cursor to the beginning of the next line.

Function 9: Display a string on the display screen

To display the string (symbol sequences), you can, of course, use the function 02, but it can be done in one reception using a 21H interrupt function 09:

DS: DX: \u003d Start Row Address

Before referring to this function, the number of the memory segment must be placed in the DS register, in which the output line is located, and in the DX register - the row offset inside this segment. At the same time, at the end of the line there should be a $ symbol (code 24h), which serves as a sign of the end of the line and is not displayed.

Although this feature may be much more convenient for functions Picky output on the screen (function 2 and 6), it has the disadvantage that a completely ordinary $ symbol is used as a string limiter. This is another side product compatibility with CP / M.

Advanced DOS operating system functions as a string limiter use CHR $ (0). This complies with the agreements adopted in the UNIX operating system and the SI programming language.

There is no such thing among DOS functions that displays numbers. Such an operation, if necessary, has to be implemented on the basis of the considered functions.

4CH function: completion of the program

After completing all its actions, the program is obliged to return the operating system management so that the user can continue to work on the PC. Such a refund is implemented by the 21h interrupt function, which is placed at the end of the program:

mOV AL,<код завершения>

Each program, generally speaking, is obliged to report, successfully or not it has completed its work. The fact is that any program is called from some other program (for example, from the operating system), and sometimes called the program to properly continue to work, you need to know whether the called program has fulfilled, or it has worked with an error. Such information is transmitted as the code of completing the program (some integer), which should be zero if the program has worked correctly, and non-zero (which is specifically stipulated in each case) otherwise. (You can learn the completion code of the program being called using the 4DH interrupt function 21H.) This code will be required or not, the program must still give it.

What is assembler

Assembler is a low-level programming language. For each processor, there is a assembler. Programming on the assembler you are working directly with the computer instrument. The source text in the assembler language consists of commands (mnemonics), which, after compiling, are converted to the processor command codes.

The development of programs on the assembler is a very hard thing. Instead of the time spent time you receive an effective program. The assembler programs are written when each processor cycle is important. At the assembler, you give specific commands to the processor and any extra garbage. This is achieved by a high speed of your program.

To competently use the assembler, you need to know the microprocessor software model. From the point of view of the programmer, the microprocessor system consists of:

  1. Microprocessor
  2. Memory
  3. I / O devices.

The software model is well described in the literature.

Assembler syntax

General format of the program string on assembler

<Метка>: <Оператор> <Операнды> ; <Комментарий>

Tags. The label can consist of characters and adhesion signs. Tags are used in conditional and unconditional transition operations.

Operator field. This field contains a team mnemonic. For example, mnemonica mOV.

Operand field. Operands may only be present if the operator is present (operator field). Operands may not be, and maybe several. Operands may be data that you need to perform some actions (forward, fold, etc.).

Comment field. The comment is needed for verbal support of the program. Everything that is behind the symbol ; It is considered a comment.

The first program in the assembler language

This article will use an assembler for I80x86 processor and the following software is used:

  • TASM - Borland Turbo Assembler - Compiler
  • Tlink - Borland Turbo Linker - Communications Editor (Linker)

To be concrete, TASM 2.0.

By tradition, our first program will withdraw the string "Hello World!" on the screen.

File sample.asm.

Model Small; Memory model.Stack 100h; Setting stack size.data; The beginning of the data segment of the Hellomsg DB program "Hello World!", 13.10, "$" .code; The beginning of the MOV AX code segment, @ data; We send the address of the data segment to the AX MOV DS register, AX; Installing the DS register to the MOV AH data segment; DOS Row Output Function on the MOV DX screen, Offset Hellomsg; We specify the offset to the beginning of the INT 21H line; We display the MOV AX string, 4C00H; DOS Function exit from the INT 21H program; Exit from END

As you might notice that the program is divided into segments: data segment, code segment and there is another stack segment.

Consider everything in order.

Directive.Model Small Specifies the memory model. Small model is 1 segment for code, 1 segment for data and stack ie Data and stack are in the same segment. There are other memory models, for example: TINY, MEDIUM, COMPACT. Depending on the memory model you chose, your program segments can overlap or may have separate segments in memory.

Directive.Stack 100H sets the size of the stack. The stack is necessary to save some information with its subsequent recovery. In particular, the stack is used during interruptions. In this case, the contents of the Flags flags register, CS Register and IP Register are stacking. Next, there is an interrupt program, and then it is restored by the values \u200b\u200bof these registers.

  • Flags Flags register contains signs that are formed after executing the command to the processor.
  • CS register (Code Segment) contains the address of the code segment.
  • The IP register (Instruction Pointer) is a command pointer. It contains the address of the command that must be completed next (address relative to the CS code segment).

More detailed description Entering the framework of a simple article.

Directive.data determines the start of the data segment of your program. The data segment defines "variables" i.e. There is a memory redundancy under the required data. After.data goes string
Hellomsg DB "Hello World!", 13.10, "$"

Here HellomSG is a symbolic name that matches the start of the line "Hello World!" (without quotes). That is, this is the address of the first symbol of our string relative to the data segment. The DB Directive (Define Byte) defines the memory area available in bypass. 13.10 - symbol codes New line And the return of the carriage, and the $ symbol is required for the correct operation of the DOS function 09H. So, our string will occupy in memory of 15 bytes.

Directive. Code determines the start of the code segment (CS - Code Segment) of the program. Next, the rows of the program containing the mnemonics of the teams.

I'll tell you about the team MOV.

mOV.<приёмник>, <источник>

MOV command - send command. She forwards the contents of the source into the receiver. Transfer can be a register register, register, memory register, but there is no transfer memory-memory. Everything passes through the processor registers.

To work with the data, you must configure the data segment register. The setting is that we record the @Data data segment address in the DS register (Data Segment). Directly record the address in this register is not possible - this is the architecture, so we use the AX register. In AX, we write a code segment address

and then we send the contents of the AX register to the DS register.

After that, the DS register will contain the address of the data segment. The DS: 0000H address will contain the H symbol. I assume that you know about segments and offsets.

The address consists of two components<Сегмент>:<Смещение>where segment is 2 bytes and offset - 2 bytes. It turns out 4 bytes to access any memory location.

mov AH, 09H
MOV DX, OFFSET Hellomsg
INT 21H.

Here we are in the AH register, write the number 09h - the number of the 21st interrupt function, which displays a string on the screen.

In the next line, we write the address (embarrassment) to the beginning of our line in the DX register.

Next, we call the interrupt 21h is the interruption of DOS functions. Interrupt - when the program being executed is interrupted and the interrupt program begins. By interrupt number, the address of the DOS subroutine is determined, which displays the character string to the screen.

You will probably have a question: why do we write the number of the function 09h in the AH register? And why is the offset to the string written to the DX register?
The answer is simple: for each function, specific registers that contain input data for this function are defined. See which registers are needed specific functions you can in Help "e.

mOV AX, 4C00H
INT 21H.

mOV AX, 4C00H - We send a function number to the AX register. Function 4C00H - Exit the program.

iNT 21H - Perform an interrupt (actually come out)

eND is the end of the program.

After the END directive, the compiler ignores everything, so you can write everything, anything :)

If you read to the end, then you are a hero!

Maiko G.V. Assembler for IBM PC: - M.: "Business Inform", "Sirin" 1999 - 212 p.



Did you like the article? Share it