-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathasm_tutorial_02.html
executable file
·354 lines (242 loc) · 8.39 KB
/
asm_tutorial_02.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
<HTML>
<HEAD>
<TITLE>8086 assembler tutorial for beginners (part 2)</TITLE>
<META name="description" content="Memory Access using 8086 Assembler">
</HEAD>
<BODY>
<FONT FACE="Verdana" SIZE=3>
<FONT SIZE=+1>
<B>8086 assembler tutorial for beginners (part 2)</B>
</FONT>
<BR><BR>
<FONT SIZE=+2><B>Memory Access</B></FONT>
<BR><BR>
To access memory we can use these four registers: <B>BX, SI, DI, BP</B>.
<BR><BR>
Combining these registers inside <B>[ ]</B> symbols, we can get different memory locations.
<BR><BR>
These combinations are supported (addressing modes):
<BR><BR>
<FONT FACE="Fixedsys">
<TABLE BORDER=1 COLS=3 CELLPADDING=10>
<TR>
<TD>
[BX + SI]<BR>
[BX + DI]<BR>
[BP + SI]<BR>
[BP + DI]<BR>
</TD>
<TD>
[SI]<BR>
[DI]<BR>
d16 (variable offset only)<BR>
[BX]<BR>
</TD>
<TD>
[BX + SI + d8]<BR>
[BX + DI + d8]<BR>
[BP + SI + d8]<BR>
[BP + DI + d8]<BR>
</TD>
</TR>
<TR>
<TD>
[SI + d8]<BR>
[DI + d8]<BR>
[BP + d8]<BR>
[BX + d8]<BR>
</TD>
<TD>
[BX + SI + d16]<BR>
[BX + DI + d16] <BR>
[BP + SI + d16]<BR>
[BP + DI + d16]<BR>
</TD>
<TD>
[SI + d16]<BR>
[DI + d16]<BR>
[BP + d16]<BR>
[BX + d16]<BR>
</TD>
</TR>
</TABLE>
</FONT>
<BR>
<B>d8</B> - stays for 8 bit signed immediate displacement (for example: 22, 55h, -1)<BR><BR>
<B>d16</B> - stays for 16 bit signed immediate displacement (for example: 300, 5517h, -259).<BR><BR>
Displacement can be a immediate value or offset of a variable, or even both.
If there are several values, assembler evaluates all values and calculates a single immediate value.
<BR><BR>
Displacement can be inside or outside of the <B>[ ]</B> symbols, assembler
generates the same machine code for both ways.
<BR><BR>
Displacement is a <B>signed</B> value, so it can be both positive or negative.
<BR><BR>
Generally the compiler takes care about difference
between <B>d8</B> and <B>d16</B>, and generates the required machine code.
<BR><BR><BR>
For example, let's assume that <B>DS = 100</B>, <B>BX = 30</B>, <B>SI = 70</B>.<BR>
The following addressing mode:
<B>[BX + SI] + 25</B>
<BR>
Is calculated by processor to this physical address: <NOBR><B>100 * 16 + 30 + 70 + 25 = 1725</B>.</NOBR>
<BR><BR>
By default <B>DS</B> segment register is used for all modes
except those with <B>BP</B> register, for these <B>SS</B> segment
register is used.
<BR><BR>
There is an easy way to remember all those possible combinations using this chart:
<BR><BR>
<IMG SRC="img/addressing_mode.gif">
<BR><BR>
All valid combinations can be formed by taking only one item from each column or skipping
the column by not taking anything from it. <B>BX</B> and <B>BP</B> never go
together. Neither <B>SI</B> and <B>DI</B> do.
<BR><BR>
Examples of valid
addressing modes:
<BR><BR>
<B>[BX+5]</B>
<BR><BR>
<B>[BX+SI]</B>
<BR><BR>
<B>[DI+BX-4]</B>
<BR><BR><BR>
<HR>
<BR><BR>
The value in segment register (CS, DS, SS, ES) is called a <B>segment</B>,
and the value in general purpose register (BX, SI, DI, BP) is called an <B>offset</B>.
<BR><BR>
When DS contains value <B>1234h</B> and SI contains the value <B>7890h</B> it can be also recorded
as <B>1234:7890</B>. The physical address will be 1234h * 10h + 7890h = 19BD0h.
<BR><BR>
If zero is added to a decimal number it is multiplied by 10, however <B>10h = 16</B>, so
If zero is added to a hexadecimal value, it is multiplied by 16, for example:
<BR><BR>
7h = 7 <BR>
70h = 112
<BR><BR><BR>
<HR>
<BR><BR>
In order to say the compiler about data type,
these prefixes should be used:<BR><BR>
<B>byte ptr</B> - for byte.<BR>
<B>word ptr</B> - for word (two bytes).<BR><BR>
for example:<BR>
<PRE><FONT FACE="Fixedsys">byte ptr [BX] ; byte access.
or
word ptr [BX] ; word access.
</FONT></PRE>
Emu Assembler supports shorter prefixes as well:<BR><BR>
<b>b.</b> - for <b>byte ptr</b><br>
<b>w.</b> - for <b>word ptr</b><br><br>
in certain cases the assembler can calculate the data type automatically.
<BR><BR><BR>
<HR>
<BR>
<FONT SIZE=+2><B><U>MOV</U> instruction</B></FONT>
<BR><BR>
<UL>
<LI>
copies the <B>second operand</B> (source) to the <B>first
operand</B> (destination).<BR><BR>
</LI>
<LI>
the source operand can be an immediate value,
general-purpose register or memory location.<BR><BR>
</LI>
<LI>
the destination register can be a general-purpose register, or memory location.<BR><BR>
</LI>
<LI>
both operands must be the same size, which can be a byte or a word.
</LI>
</UL>
<TABLE BORDER=1 CELLPADDING=10 WIDTH=100%><TR><TD>
these types of operands are supported:<BR><BR>
<BLOCKQUOTE>
<FONT FACE="Fixedsys">
MOV REG, memory<BR>
MOV memory, REG<BR>
MOV REG, REG<BR>
MOV memory, immediate<BR>
MOV REG, immediate
</FONT>
</BLOCKQUOTE>
<B>REG</B>:<FONT SIZE=-1> AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.</FONT><BR><BR>
<B>memory</B>: [BX], [BX+SI+7], variable<BR><BR>
<B>immediate</B>: 5, -24, 3Fh, 10001101b<BR><BR>
</TD></TR></TABLE>
<BR>
<TABLE BORDER=1 CELLPADDING=10 WIDTH=100%><TR><TD>
for segment registers only these types of <B>MOV</B> are supported:<BR><BR>
<BLOCKQUOTE>
<FONT FACE="Fixedsys">
MOV SREG, memory<BR>
MOV memory, SREG<BR>
MOV REG, SREG<BR>
MOV SREG, REG<BR>
</FONT>
</BLOCKQUOTE>
<B>SREG</B>: DS, ES, SS, and only as second operand: CS.<BR><BR>
<B>REG</B>:<FONT SIZE=-1> AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.</FONT><BR><BR>
<B>memory</B>: [BX], [BX+SI+7], variable<BR><BR>
</TD></TR></TABLE>
<BR>
The <B>MOV</B> instruction <U>cannot</U> be used to set the value of
the <B>CS</B> and <B>IP</B> registers.
<BR><BR>
<TABLE BORDER=1 CELLPADDING=10 WIDTH=100%><TR><TD>
A short program that demonstrates the use of <B>MOV</B> instruction:
<!-- START AUTOMATIC ASM TO HTML EXPORT -->
<pre><font face="Terminal">
<font color=#000064>ORG</font> 100h <font color=#008000>; this directive required for a simple 1 segment .com program. </font>
<font color=#0000FF>MOV</font> <font color=#C80000>AX</font>, 0B800h <font color=#008000>; set AX to hexadecimal value of B800h. </font>
<font color=#0000FF>MOV</font> <font color=#800000>DS</font>, <font color=#C80000>AX</font> <font color=#008000>; copy value of AX to DS. </font>
<font color=#0000FF>MOV</font> <font color=#C80000>CL</font>, <font color=#800080>'A'</font> <font color=#008000>; set CL to ASCII code of 'A', it is 41h. </font>
<font color=#0000FF>MOV</font> <font color=#C80000>CH</font>, 1101_1111b <font color=#008000>; set CH to binary value. </font>
<font color=#0000FF>MOV</font> <font color=#C80000>BX</font>, 15Eh <font color=#008000>; set BX to 15Eh. </font>
<font color=#0000FF>MOV</font> <font color=#0064C8>[</font><font color=#C80000>BX</font><font color=#0064C8>]</font>, <font color=#C80000>CX</font> <font color=#008000>; copy contents of CX to memory at B800:015E </font>
<font color=#0000FF>RET</font> <font color=#008000>; returns to operating system. </font>
</font></pre>
<!-- STOP AUTOMATIC ASM TO HTML EXPORT -->
</TD></TR></TABLE>
<BR><BR>
Once the above program is typed into the code editor,
and [<B>Compile and Emulate</B>] button is pressed (<B>F5</B> key)<BR>
<BR>
The emulator window should open with this program loaded, clicking
<NOBR>[<B>Single Step</B>]</NOBR>
button should change the register values.<BR>
<BR><BR>
How to do <B>copy & paste</B>: <BR>
<OL>
<LI>
Select the above text using mouse, click before the text
and drag it down until everything is selected.<BR><BR></LI>
<LI>Press <B>Ctrl + C</B> combination to copy.<BR><BR></LI>
<LI>Click inside the source code editor and press <B>Ctrl + V</B>
combination to paste.</LI>
</OL>
<BR><BR>
"<B>;</B>" is used for comments, anything after "<B>;</B>" symbol
is ignored.<BR><BR>
<BR>
The result of a working program:<BR><BR>
<IMG SRC="img/screen01.gif">
<BR><BR>
Actually the above program writes directly to video memory, now we can see that <B>MOV</B>
is a very powerful instruction.
<BR><BR><BR>
<HR>
<CENTER>
<A HREF="asm_tutorial_01.html"><B> <<< previous part <<< </B></A>
<A HREF="asm_tutorial_03.html"><B> >>> Next Part >>> </B></A>
</CENTER>
<HR>
<BR>
</FONT>
</BODY>
</HTML>