]> 4ch.mooo.com Git - 16.git/blob - 16/PCGPE10/ASMINTRO.TXT
reverted my open watcom to 1.9 an recompiled everything~
[16.git] / 16 / PCGPE10 / ASMINTRO.TXT
1 \r
2         ÖÄÄÄÄÄÄÄÄÄÄ´% VLA Presents: Intro to Assembler %ÃÄÄÄÄÄÄÄÄÄÄ·\r
3         º                                                          º\r
4         ÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ\r
5 \r
6 \r
7 \r
8   ¯ Dedicated To Those Who Wish To Begin Exploring The Art Of Assembler. ®\r
9 \r
10 \r
11 \r
12 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \ 4 VLA Members Are \ 4 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
13 \r
14                          (© Draeden - Main Coder ª)\r
15                       (© The Priest - Coder/ Artist ª)\r
16                   (© Lithium -  Coder/Ideas/Ray Tracing ª)\r
17                    (© The Kabal -  Coder/Ideas/Artwork ª)\r
18                       (© Desolation - Artwork/Ideas ª)\r
19 \r
20 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The Finn - Mods/Sounds ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
21 \r
22 \r
23    ÖÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ͵ Contact Us On These Boards ÆÍÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ·\r
24    º                                                                    º\r
25    ³  % Phantasm BBS .................................. (206) 232-5912  ³\r
26    ³  * The Deep ...................................... (305) 888-7724  ³\r
27    ³  * Dark Tanget Systems ........................... (206) 722-7357  ³\r
28    ³  * Metro Holografix .............................. (619) 277-9016  ³\r
29    ³                                                                    ³\r
30    º        % - World Head Quarters      * - Distribution Site          º\r
31    ÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ\r
32 \r
33      Or Via Internet Mail For The Group: tkabal@carson.u.washington.edu\r
34 \r
35                        Or to reach the other members:\r
36 \r
37                         - draeden@u.washington.edu -\r
38 \r
39                         - lithium@u.washington.edu -\r
40 \r
41                        - desolation@u.washington.edu-\r
42 \r
43 \r
44 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
45     VLA 3/93  Introduction to ASSEMBLER\r
46 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
47 \r
48 Here's something to help those of you who were having trouble understanding\r
49 the instructional programs we released.  Dreaden made these files for the \r
50 Kabal and myself when we were just learning.  These files go over some of \r
51 the basic concepts of assembler.  Bonus of bonuses.  These files also have \r
52 programs imbedded in them.  Most of them have a ton of comments so even\r
53 the beginning programmers should be able to figure them out.\r
54 \r
55 If you'd like to learn more, post a message on Phantasm.  We need to know\r
56 where you're interests are before we can make more files to bring out the\r
57 little programmers that are hiding inside all of us.\r
58 \r
59     Lithium/VLA\r
60 \r
61 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
62 \r
63     First thing ya need to know is a little jargon so you can talk about \r
64 the basic data structures with your friends and neighbors.  They are (in\r
65 order of increasing size) BIT, NIBBLE, BYTE, WORD, DWORD, FWORD, PWORD and\r
66 QWORD, PARA, KiloByte, MegaByte.  The ones that you'll need to memorize are\r
67 BYTE, WORD, DWORD, KiloByte, and MegaByte.  The others aren't used all that \r
68 much, and you wont need to know them to get started.  Here's a little \r
69 graphical representation of a few of those data structures:\r
70 \r
71 (The zeros in between the || is a graphical representation of the number of\r
72 bits in that data structure.)\r
73 \r
74 ÄÄÄÄÄÄ\r
75 1 BIT :     |0|\r
76 \r
77     The simplest piece of data that exists.  Its either a 1 or a zero.\r
78     Put a string of them together and you have a BASE-2 number system.\r
79     Meaning that instead of each 'decimal' place being worth 10, its only \r
80     worth 2.  For instance: 00000001 = 1; 00000010 = 2; 00000011 = 3, etc..\r
81 \r
82 ÄÄÄÄÄÄ\r
83 1 NIBBLE:   |0000|\r
84 4 BITs\r
85 \r
86     The NIBBLE is half a BYTE or four BITS.  Note that it has a maximum value\r
87     of 15 (1111 = 15).  Not by coincidence, HEXADECIMAL, a base 16 number \r
88     system (computers are based on this number system) also has a maximum \r
89     value of 15, which is represented by the letter 'F'.  The 'digits' in\r
90     HEXADECIMAL are (in increasing order): \r
91     \r
92     "0123456789ABCDEF"\r
93 \r
94     The standard notation for HEXADECIMAL is a zero followed by the number        \r
95     in HEX followed by a lowercase "h"  For instance: "0FFh" = 255 DECIMAL.\r
96 \r
97 ÄÄÄÄÄÄ\r
98 1 BYTE      |00000000|\r
99 2 NIBBLEs    ÀÄ AL ÄÙ\r
100 8 BITs\r
101 \r
102     The BYTE is the standard chunk of information.  If you asked how much \r
103     memory a machine had, you'd get a response stating the number of BYTEs it\r
104     had. (Usually preceded by a 'Mega' prefix).  The BYTE is 8 BITs or \r
105     2 NIBBLEs.  A BYTE has a maximum value of 0FFh (= 255 DECIMAL).  Notice\r
106     that because a BYTE is just 2 NIBBLES, the HEXADECIMAL representation is\r
107     simply two HEX digits in a row (ie. 013h, 020h, 0AEh, etc..)\r
108 \r
109     The BYTE is also that size of the 'BYTE sized' registers - AL, AH, BL, BH,\r
110     CL, CH, DL, DH.\r
111 \r
112 ÄÄÄÄÄÄ\r
113 1  WORD      |0000000000000000|\r
114 2  BYTEs      ÀÄ AH ÄÙÀÄ AL ÄÙ     \r
115 4  NIBBLEs    ÀÄÄÄÄÄ AX ÄÄÄÄÄÙ\r
116 16 BITs\r
117 \r
118     The WORD is just two BYTEs that are stuck together.  A word has a maximum \r
119     value of 0FFFFh (= 65,535).  Since a WORD is 4 NIBBLEs, it is represented\r
120     by 4 HEX digits.  This is the size of the 16bit registers on the 80x86\r
121     chips.  The registers are: AX, BX, CX, DX, DI, SI, BP, SP, CS, DS, ES, SS,\r
122     and IP.  Note that you cannot directly change the contents of IP or CS in \r
123     any way.  They can only be changed by JMP, CALL, or RET.\r
124 \r
125 ÄÄÄÄÄÄ\r
126 1  DWORD\r
127 2  WORDs     |00000000000000000000000000000000|\r
128 4  BYTEs      ³               ÀÄ AH ÄÙÀÄ AL ÄÙ     \r
129 8  NIBBLEs    ³               ÀÄÄÄÄÄ AX ÄÄÄÄÄÙ\r
130 32 BITs       ÀÄÄÄÄÄÄÄÄÄÄÄÄ EAX ÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
131 \r
132     A DWORD (or "DOUBLE WORD") is just two WORDs, hence the name DOUBLE-WORD.\r
133     This can have a maximum value of 0FFFFFFFFh (8 NIBBLEs, 8 'F's) which\r
134     equals 4,294,967,295.  Damn large.  This is also the size or the 386's\r
135     32bit registers: EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP, EIP.  The 'E '\r
136     denotes that they are EXTENDED registers.  The lower 16bits is where the \r
137     normal 16bit register of the same name is located. (See diagram.)\r
138 \r
139 ÄÄÄÄÄÄ\r
140 1    KILOBYTE   |-lots of zeros (8192 of 'em)-|\r
141 256  DWORDs\r
142 512  WORDs\r
143 1024 BYTEs\r
144 2048 NIBBLEs\r
145 8192 BITs\r
146 \r
147     We've all heard the term KILOBYTE byte, before, so I'll just point out\r
148     that a KILOBYTE, despite its name, is -NOT- 1000 BYTEs.  It is actually\r
149     1024 bytes.\r
150 \r
151 ÄÄÄÄÄÄ\r
152           1 MEGABYTE   |-even more zeros (8,388,608 of 'em)-|\r
153       1,024 KILOBYTEs\r
154     262,144 DWORDs\r
155     524,288 WORDs\r
156   1,048,576 BYTEs\r
157   2,097,152 NIBBLEs\r
158   8,388,608 BITs\r
159 \r
160     Just like the KILOBYTE, the MEGABYTE is -NOT- 1 million bytes.  It is\r
161     actually 1024*1024 BYTEs, or 1,048,578 BYTEs\r
162 \r
163 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
164 \r
165     Now that we know what the different data types are, we will investigate\r
166     an annoying little aspect of the 80x86 processors.  I'm talking about \r
167     nothing other than SEGMENTS & OFFSETS!\r
168 \r
169 \r
170 SEGMENTS & OFFSETS:\r
171 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
172     Pay close attention, because this topic is (I believe) the single most\r
173     difficult (or annoying, once you understand it) aspect of ASSEMBLER.\r
174 \r
175 An OverView:\r
176 \r
177     The original designers of the 8088, way back when dinasaurs ruled the \r
178     planet, decided that no one would ever possibly need more than one MEG\r
179     (short for MEGABYTE :) of memory.  So they built the machine so that it \r
180     couldn't access above 1 MEG. To access the whole MEG, 20 BITs are needed.\r
181     Problem was that the registers only had 16 bits, and if the used two\r
182     registers, that would be 32 bits, which was way too much (they thought.)  \r
183     So they came up with a rather brilliant (blah) way to do their addressing-\r
184     they would use two registers.  They decided that they would not be 32bits, \r
185     but the two registers would create 20 bit addressing.  And thus Segments\r
186     and OFfsets were born.  And now the confusing specifics.\r
187 \r
188 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
189     \r
190 OFFSET  = SEGMENT*16\r
191 SEGMENT = OFFSET /16    ;note that the lower 4 bits are lost\r
192 \r
193                  \r
194 SEGMENT * 16    |0010010000010000----|  range (0 to 65535) * 16\r
195  +                    \r
196 OFFSET          |----0100100000100010|  range (0 to 65535)\r
197  =\r
198 20 bit address  |00101000100100100010|  range 0 to 1048575 (1 MEG)\r
199                  ÀÄÄÄÄÄ DS ÄÄÄÄÄÙ\r
200                      ÀÄÄÄÄÄ SI ÄÄÄÄÄÙ\r
201                      ÀÄ OverlapÄÙ\r
202 \r
203  This shows how DS:SI is used to construct a 20 bit address.\r
204 \r
205 Segment registers are: CS, DS, ES, SS. On the 386+ there are also FS & GS\r
206 \r
207 Offset registers  are: BX, DI, SI, BP, SP, IP.  In 386+ protected mode, ANY\r
208         general register (not a segment register) can be used as an Offset\r
209         register.  (Except IP, which you can't access.)\r
210 \r
211     CS:IP => Points to the currently executing code.\r
212     SS:SP => Points to the current stack position.\r
213     \r
214 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
215 \r
216     If you'll notice, the value in the SEGMENT register is multiplied by\r
217     16 (or shifted left 4 bits) and then added to the OFFSET register.\r
218     Together they create a 20 bit address.  Also Note that there are MANY\r
219     combinations of the SEGMENT and OFFSET registers that will produce the \r
220     same address.  The standard notation for a SEGment/OFFset pair is:\r
221 \r
222 ÄÄÄÄ\r
223 SEGMENT:OFFSET or A000:0000 ( which is, of course in HEX )\r
224 \r
225     Where SEGMENT = 0A000h and OFFSET = 00000h.  (This happens to be the \r
226     address of the upper left pixel on a 320x200x256 screen.)\r
227 ÄÄÄÄ\r
228 \r
229     You may be wondering what would happen if you were to have a segment\r
230     value of 0FFFFh and an offset value of 0FFFFh.  \r
231 \r
232     Take notice: 0FFFFh * 16 (or 0FFFF0h ) + 0FFFFh = 1,114,095, which is \r
233       definately larger than 1 MEG (which is 1,048,576.)\r
234 \r
235     This means that you can actually access MORE than 1 meg of memory!  \r
236     Well, to actually use that extra bit of memory, you would have to enable\r
237     something called the A20 line, which just enables the 21st bit for\r
238     addressing.  This little extra bit of memory is usually called\r
239     "HIGH MEMORY" and is used when you load something into high memory or\r
240     say DOS = HIGH in your AUTOEXEC.BAT file.  (HIMEM.SYS actually puts it up\r
241     there..)  You don't need to know that last bit, but hey, knowledge is \r
242     good, right?\r
243 \r
244 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
245     THE REGISTERS:\r
246 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
247 \r
248     I've mentioned AX, AL, and AH before, and you're probably wondering what\r
249     exactly they are.  Well, I'm gonna go through one by one and explain\r
250     what each register is and what it's most common uses are.  Here goes:\r
251 \r
252 ÄÄÄÄ\r
253 AX (AH/AL): \r
254     AX is a 16 bit register which, as metioned before, is merely two bytes\r
255     attached together.  Well, for AX, BX, CX, & DX you can independantly \r
256     access each part of the 16 bit register through the 8bit (or byte sized)\r
257     registers.  For AX, they are AL and AH, which are the Low and High parts\r
258     of AX, respectivly.  It should be noted that any change to AL or AH, \r
259     will change AX.  Similairly any changes to AX may or may not change AL and\r
260     AH.  For instance:\r
261 \r
262 ÄÄÄÄÄÄÄÄ\r
263 Let's suppose that AX = 00000h (AH and AL both = 0, too) \r
264 \r
265     mov     AX,0\r
266     mov     AL,0\r
267     mov     AH,0\r
268 \r
269 Now we set AL = 0FFh.  \r
270  \r
271     mov     AL,0FFh\r
272 \r
273 :AX => 000FFh  ;I'm just showing ya what's in the registers\r
274 :AL =>   0FFh\r
275 :AH => 000h\r
276 \r
277 Now we increase AX by one:\r
278 \r
279     INC     AX\r
280 \r
281 :AX => 00100h (= 256.. 255+1= 256)\r
282 :AL =>   000h (Notice that the change to AX changed AL and AH)\r
283 :AH => 001h\r
284 \r
285 Now we set AH = 0ABh (=171)\r
286 \r
287     mov     AH,0ABh\r
288 \r
289 :AX => 0AB00h\r
290 :AL =>   000h\r
291 :AH => 0ABh\r
292 \r
293 Notice that the first example was just redundant...\r
294 We could've set AX = 0 by just doing\r
295 \r
296     mov     ax,0\r
297 \r
298 :AX => 00000h\r
299 :AL =>   000h\r
300 :AH => 000h\r
301 \r
302 I think ya got the idea...\r
303 ÄÄÄÄÄÄÄÄ\r
304 \r
305     SPECIAL USES OF AX:\r
306         Used as the destination of an IN (in port) \r
307             ex: IN  AL,DX\r
308                 IN  AX,DX\r
309 \r
310         Source for the output for an OUT           \r
311             ex: OUT DX,AL\r
312                 OUT DX,AX\r
313 \r
314         Destination for LODS (grabs byte/word from [DS:SI] and INCreses SI)\r
315             ex: lodsb   (same as:   mov al,[ds:si] ; inc si )\r
316                 lodsw   (same as:   mov ax,[ds:si] ; inc si ; inc si )\r
317 \r
318         Source for STOS      (puts AX/AL into [ES:DI] and INCreses DI)\r
319             ex: stosb   (same as:   mov [es:di],al ; inc di )\r
320                 stosw   (same as:   mov [es:di],ax ; inc di ; inc di )\r
321 \r
322         Used for MUL, IMUL, DIV, IDIV\r
323 ÄÄÄÄ\r
324 BX (BH/BL): same as AX (BH/BL)\r
325 \r
326     SPECIAL USES:\r
327         As mentioned before, BX can be used as an OFFSET register.\r
328             ex: mov ax,[ds:bx]  (grabs the WORD at the address created by\r
329                                     DS and BX)\r
330 \r
331 CX (CH/CL): Same as AX\r
332     \r
333     SPECIAL USES:\r
334         Used in REP prefix to repeat an instruction CX number of times\r
335             ex: mov cx,10\r
336                 mov ax,0\r
337                 rep stosb ;this would write 10 zeros to [ES:DI] and increase\r
338                           ;DI by 10.\r
339         Used in LOOP\r
340             ex: mov cx,100\r
341             THELABEL:\r
342 \r
343                 ;do something that would print out 'HI'\r
344 \r
345                 loop THELABEL   ;this would print out 'HI' 100 times\r
346                                 ;the loop is the same as: dec cx\r
347                                                           jne THELABAL\r
348             \r
349 DX (DH/DL): Same as above\r
350     SPECIAL USES:\r
351         USED in word sized MUL, DIV, IMUL, IDIV as DEST for high word\r
352                 or remainder\r
353 \r
354             ex: mov bx,10\r
355                 mov ax,5\r
356                 mul bx  ;this multiplies BX by AX and puts the result \r
357                         ;in DX:AX\r
358 \r
359             ex: (continue from above)\r
360                 div bx  ;this divides DX:AX by BX and put the result in AX and\r
361                         ;the remainder (in this case zero) in DX\r
362 \r
363         Used as address holder for IN's, and OUT's (see ax's examples)\r
364             \r
365 INDEX REGISTERS:  \r
366 \r
367     DI: Used as destination address holder for stos, movs (see ax's examples)\r
368         Also can be used as an OFFSET register\r
369 \r
370     SI: Used as source address holder for lods, movs (see ax's examples)\r
371         Also can be used as OFFSET register\r
372 \r
373         Example of MOVS:\r
374             movsb   ;moves whats at [DS:SI] into [ES:DI] and increases\r
375             movsw   ; DI and SI by one for movsb and 2 for movsw\r
376 \r
377         NOTE: Up to here we have assumed that the DIRECTION flag was cleared.\r
378             If the direction flag was set, the DI & SI would be DECREASED \r
379             instead of INCREASED.\r
380             ex:     cld     ;clears direction flag\r
381                     std     ;sets direction flag\r
382 \r
383 STACK RELATED INDEX REGISTERS:\r
384     BP: Base Pointer. Can be used to access the stack. Default segment is\r
385         SS.  Can be used to access data in other segments throught the use\r
386         of a SEGMENT OVERRIDE.\r
387 \r
388         ex: mov al,[ES:BP] ;moves a byte from segment ES, offset BP\r
389             Segment overrides are used to specify WHICH of the 4 (or 6 on the\r
390             386) segment registers to use.\r
391 \r
392     SP: Stack Pointer. Does just that.  Segment overrides don't work on this \r
393         guy.  Points to the current position in the stack.  Don't alter unless\r
394         you REALLY know what you are doing.\r
395         \r
396 SEGMENT REGISTERS:\r
397     DS: Data segment- all data read are from the segment pointed to be this\r
398         segment register unless a segment overide is used.\r
399         Used as source segment for movs, lods\r
400         This segment also can be thought of as the "Default Segment" because\r
401         if no segment override is present, DS is assumed to be the segmnet\r
402         you want to grab the data from.\r
403 \r
404     ES: Extra Segment- this segment is used as the destination segment\r
405         for movs, stos\r
406         Can be used as just another segment...  You need to specify [ES:°°]\r
407         to use this segment.\r
408 \r
409     FS: (386+) No particular reason for it's name... I mean, we have CS, DS,\r
410         and ES, why not make the next one FS? :)  Just another segment..\r
411     \r
412     GS: (386+) Same as FS\r
413 \r
414     \r
415 OTHERS THAT YOU SHOULDN'T OR CAN'T CHANGE:\r
416     CS: Segment that points to the next instruction- can't change directly\r
417     IP: Offset pointer to the next instruction- can't even access\r
418         The only was to change CS or IP would be through a JMP, CALL, or RET\r
419 \r
420     SS: Stack segment- don't mess with it unless you know what you're\r
421         doing.  Changing this will probably crash the computer.  This is the\r
422         segment that the STACK resides in.\r
423 \r
424 ÄÄÄÄÄÄÄÄ\r
425 Heck, as long as I've mentioned it, lets look at the STACK:\r
426 \r
427     The STACK is an area of memory that has the properties of a STACK of\r
428     plates- the last one you put on is the first one take off.  The only\r
429     difference is that the stack of plates is on the roof.  (Ok, so that\r
430     can't really happen... unless gravity was shut down...)  Meaning that\r
431     as you put another plate (or piece of data) on the stack, the STACK grows\r
432     DOWNWARD.  Meaning that the stack pointer is DECREASED after each PUSH,\r
433     and INCREASED after each POP.\r
434 \r
435   _____ Top of the allocated memory in the stack segment (SS)\r
436     þ \r
437     þ\r
438     þ\r
439     þ ® SP (the stack pointer points to the most recently pushed byte)\r
440 \r
441     Truthfully, you don't need to know much more than a stack is Last In,\r
442     First Out (LIFO).\r
443 \r
444   WRONG ex: push    cx  ;this swaps the contents of CX and AX\r
445             push    ax  ;of course, if you wanted to do this quicker, you'd\r
446             ...\r
447             pop     cx  ;just say XCHG cx,ax\r
448             pop     ax  ; but thats not my point.\r
449 \r
450   RIGHT ex: push    cx  ;this correctly restores AX & CX  \r
451             push    ax\r
452             ...\r
453             pop     ax\r
454             pop     cx\r
455 \r
456 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
457 \r
458 Now I'll do a quick run through on the assembler instructions that you MUST\r
459 know:\r
460 \r
461 ÄÄÄÄ\r
462 MOV:\r
463 \r
464     Examples of different addressing modes: \r
465 \r
466         MOV ax,5        ;moves and IMMEDIATE value into ax (think 'AX = 5')\r
467         MOV bx,cx       ;moves a register into another register\r
468         MOV cx,[SI]     ;moves [DS:SI] into cx (the Default Segment is Used)\r
469         MOV [DI+5],ax   ;moves ax into [DS:DI+5]\r
470         MOV [ES:DI+BX+34],al    ;same as above, but has a more complicated\r
471                                 ;OFFSET (=DI+BX+34) and a SEGMENT OVERRIDE\r
472         MOV ax,[546]    ;moves whats at [DS:546] into AX\r
473                         \r
474     Note that the last example would be totally different if the brackets \r
475     were left out.  It would mean that an IMMEDIATE value of 546 is put into\r
476     AX, instead of what's at offset 546 in the Default Segment.\r
477     \r
478 ANOTHER STANDARD NOTATION TO KNOW:\r
479     Whenever you see brackets [] around something, it means that it refers to \r
480     what is AT that offset.  For instance, say you had this situation:\r
481 \r
482 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
483 MyData  dw  55\r
484     ...\r
485     mov ax,MyData\r
486 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
487 \r
488     What is that supposed to mean?  Is MyData an Immediate Value?  This is\r
489     confusing and for our purposes WRONG.  The 'Correct' way to do this would\r
490     be:\r
491 \r
492 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
493 MyData  dw  55\r
494     ...\r
495     mov ax,[MyData]\r
496 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
497 \r
498     This is clearly moving what is AT the address of MyData, which would be\r
499     55, and not moving the OFFSET of MyData itself.  But what if you \r
500     actually wanted the OFFSET?  Well, you must specify directly.\r
501 \r
502 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
503 MyData  dw  55\r
504     ...\r
505     mov ax,OFFSET MyData\r
506 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
507 \r
508     Similiarly, if you wanted the SEGMENT that MyData was in, you'd do this:\r
509 \r
510 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
511 MyData  dw  55\r
512     ...\r
513     mov ax,SEG MyData\r
514 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
515 \r
516 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
517 INT:\r
518     Examples:\r
519         INT 21h     ;calls DOS standard interrupt # 21h\r
520         INT 10h     ;the Video BIOS interrupt..\r
521         \r
522     INT is used to call a subroutine that performs some function that you'd\r
523     rather not write yourself.  For instance, you would use a DOS interrupt \r
524     to OPEN a file.  You would similiarly use the Video BIOS interrupt to\r
525     set the screen mode, move the cursor, or to do any other function that \r
526     would be difficult to program.\r
527 \r
528     Which subroutine the interrupt preforms is USUALLY specified by AH.\r
529     For instance, if you wanted to print a message to the screen you'd\r
530     use INT 21h, subfunction 9 by doing this:\r
531 \r
532 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
533     mov ah,9\r
534     int 21h\r
535 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
536 \r
537     Yes, it's that easy.  Of course, for that function to do anything, you\r
538     need to specify WHAT to print.  That function requires that you have\r
539     DS:DX be a FAR pointer that points to the string to display.  This string\r
540     must terminate with a dollar sign.  Here's an example:\r
541 \r
542 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
543 MyMessage db    "This is a message!$" \r
544     ...\r
545     mov     dx,OFFSET MyMessage\r
546     mov     ax,SEG MyMessage\r
547     mov     ds,ax\r
548     mov     ah,9\r
549     int     21h\r
550     ...\r
551 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
552 \r
553     The DB, like the DW (and DD) merely declares the type of a piece of data.\r
554 \r
555         DB => Declare Byte (I think of it as 'Data Byte')\r
556         DW => Declare Word\r
557         DD => Declare Dword\r
558     \r
559     Also, you may have noticed that I first put the segment value into AX\r
560     and then put it into DS.  I did that because the 80x86 does NOT allow\r
561     you to put an immediate value into a segment register.  You can, however,\r
562     pop stuff into a Segment register or mov an indexed value into the\r
563     segment register.  A few examples:\r
564 \r
565 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
566   LEGAL:\r
567     mov     ax,SEG MyMessage\r
568     mov     ds,ax\r
569 \r
570     push    SEG Message\r
571     pop     ds\r
572 \r
573     mov     ds,[SegOfMyMessage]     \r
574             ;where [SegOfMyMessage] has already been loaded with \r
575             ; the SEGMENT that MyMessage resides in\r
576   ILLEGAL:\r
577     mov     ds,10\r
578     mov     ds,SEG MyMessage\r
579 ÄÄÄÄÄÄÄÄÄÄÄÄ\r
580 \r
581 Well, that's about it for what you need to know to get started...\r
582 \r
583 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
584     And now the FRAME for an ASSEMBLER program.\r
585 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
586 \r
587 The Basic Frame for an Assembler program using Turbo Assembler simplified\r
588     directives is:\r
589 \r
590 ;===========-\r
591 \r
592     DOSSEG  ;This arranges the segments in order according DOS standards\r
593             ;CODE, DATA, STACK\r
594     .MODEL SMALL    ;dont worry about this yet\r
595     .STACK  200h    ;tells the compiler to put in a 200h byte stack\r
596     .CODE           ;starts code segment\r
597 \r
598     ASSUME  CS:@CODE, DS:@CODE \r
599 \r
600 START:      ;generally a good name to use as an entry point\r
601 \r
602     mov     ax,4c00h\r
603     int     21h\r
604 \r
605 END START\r
606 \r
607 ;===========- By the way, a semicolon means the start of a comment.\r
608 \r
609     If you were to enter this program and TASM & TLINK it, it would execute\r
610     perfectly.  It will do absolutly nothing, but it will do it well.\r
611 \r
612     What it does:\r
613         Upon execution, it will jump to START. move 4c00h into AX,\r
614         and call the DOS interrupt, which exits back to DOS.\r
615 \r
616         Outout seen: NONE\r
617 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
618 \r
619 That's nice, eh?  If you've understood the majority of what was presented \r
620 in this document, you are ready to start programming!\r
621 \r
622 See ASM0.TXT and ASM0.ASM to continue this wonderful assembler stuff...\r
623 \r
624 \r
625 Written By Draeden/VLA\r
626 \r