⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap03.html

📁 vid写的FASM向导
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<blockquote class="code"><pre>
label variable1 word
dw <font color=#339933>1000</font>
</pre></blockquote>

now everytime you use <code>[variable1]</code> it will have same meaning as
<code>byte [variable1]</code> (or <code>word [variable1]</code> in second
example). So <code>mov [variable1],10</code> will work, in first case it will
store value 10 to byte at address <code>variable1</code>, in second case it
will store to word.

<blockquote class="term">
<b>size operator</b><br>
</blockquote>

<b>NOTE:</b> You can't move value between variables with different size:
<blockquote class="code"><pre>
mov byte <font color=#333399>[</font>variable1<font color=#333399>],</font> word <font color=#339933>10</font>
</pre></blockquote>
or
<blockquote class="code"><pre>
mov <font color=#333399>[</font>variable1<font color=#333399>],</font>al
...
label variable1 word
dw <font color=#339933>0</font>
</pre></blockquote>
<br>
<b>NOTE:</b> You can't access two memory locations in one instruction (except for
same special instructions). This is wrong, it won't be compiled:
<blockquote class="code"><pre>
mov <font color=#333399>[</font>variable1<font color=#333399>],[</font>variable2<font color=#333399>]</font>
</pre></blockquote>

use this:
<blockquote class="code"><pre>
mov al<font color=#333399>,[</font>variable2<font color=#333399>]</font>
mov <font color=#333399>[</font>variable1<font color=#333399>],</font>al
</pre></blockquote>

This will cause you some problems in the beginning but it will force you
to write faster code, and that is biggest reason to code assembly.<br><br>

<b>NOTE:</b> size operator assigned to label at definition has lower priority than
size operator before access to variable in instruction, so:
<blockquote class="code"><pre>
mov byte <font color=#333399>[</font>variable<font color=#333399>],</font><font color=#339933>10</font>
label variable word
dw <font color=#339933>0</font>
</pre></blockquote>

will access BYTE, while
<blockquote class="code"><pre>
mov <font color=#333399>[</font>variable<font color=#333399>],</font><font color=#339933>10</font>
</pre></blockquote>

will access WORD.<br><br>

I think you noticed that having two lines to define one variable is little too
much. There is a shorter way to define variable:
<blockquote class="code"><pre>
variable1 db <font color=#339933>100</font>
</pre></blockquote>

is same as
<blockquote class="code"><pre>
label variable1 byte
db <font color=#339933>100</font>
</pre></blockquote>

notice that size of variable is defined too. In general, if data definiton
(using <code>db</code> or <code>dw</code> directive) is preceded by label, then
it will define this label too, and assign size of defined data as size of
label.

It can be used with words too
<blockquote class="code"><pre>
variable2 dw <font color=#339933>100</font>
</pre></blockquote>

Some example of using variables:
<blockquote class="code"><pre>
mov ah<font color=#333399>,</font><font color=#339933>2</font>
mov dl<font color=#333399>,[</font>character_to_write<font color=#333399>]</font>
int <font color=#339933>21h</font>
int <font color=#339933>20h</font>
character_to_write db <font color=#bb0000>'a'</font>
</pre></blockquote>
<br><br>

<b>3.3. Addresses and basics of segmentation</b>

<br>
Now we will discuss addresses little more. I have told that address is number
(<b>!</b>) which gives some position in memory. You have learnt how to represent this
number with labels, so numeric addresses were maintained by compiler. But you
still don't know anything about format of this number. I will try to explain
it a little in this chapter.<br><br>

As you probably know, data in memory are stored in "bits" which can have value
0 or 1. You can consider memory as a (one dimensional) array of bits. 8
consecutive bits make one byte.  Address is number (index, position in array)
of byte. For example address "0" is address of first bit of memory (or address
of first byte), address "1" is address of eight bit (or address of second byte)
of memory etc. Easiest to comprehend is to take memory as (one dimensional)
array of bytes<br><br>

Address in .COM files is word-sized number, so
<blockquote class="code"><pre>
label var1
<font color=#333399>&lt;</font>some data<font color=#333399>&gt;</font>
mov al<font color=#333399>,</font>var1
</pre></blockquote>

is wrong. It may work if <code>var1</code> is lesser than 256 so it fits into
byte sized register, but in general, store addresses in word-sized variables,
we will talk about them little later.<br><br>

Now some examples on addresses. Check this file
<blockquote class="code"><pre>
label variable1
db <font color=#339933>10</font>
label variable2
db <font color=#339933>20</font>
label variable3
db <font color=#339933>30</font>
</pre></blockquote>

here address represented by <code>variable1</code> is 0, <code>variable2</code>
stands for 1, <code>variable3</code> is 2.<br><br>

OK, this looks nice but it is not true at all. Problem is that there are
usually more programs loaded in memory at same time (operating system, mouse
driver, you program etc.). When using this way, program would have to know
WHERE in memory will it be loaded so it can access it's variables. For this
reason addresses are "relative". It means that for every program that is
loaded is reserved some region in memory called "segment". All addresses in
memory accessed by this program is then relative to begginning of this area.
So <code>[0]</code> doesn't mean first byte of memory, but first byte of segment.

<blockquote class="term">
<b>segment</b><br>
consecutive region of memory reserved for one program
</blockquote>

How this works? Processor has few special registers (segment registers) which
holds address of segment (address of first byte of segment). Every time you
access memory in your program then contents of this segment register is added
to address given by you so <code>mov al,[0]</code> accesses first byte of your
segment.<br><br>

<b>NOTE:</b> I have told that memory addresses in .COM programs are words. That
means they can be in range 0 to 65535. So maximal size of one segment is
65536 bytes. This can be "tricked" by changing contents of segment registers,
but don't care about this now.<br><br>

<b>NOTE:</b> Segment is region in memory. But term "segment" is often used for
address of beginning of this region. Sad but true.<br><br>

So absolute address in memory has two parts: segment (exact: address of
beggining of segment) and second part, word sized value called "offset" which
is address relative to segment (address of beginning of segment).

<blockquote class="term">
<b>offset</b><br>
address relative to segment, or address "inside" segment. (first definition is more
exact, but second is easier to comprehend)
</blockquote>

<b>NOTE:</b> (important) I said labels represent address of variable. In fact,
labels in FASM represent offset of variable. That is why it called "flat"
(you will comprehend this later (much much later :))<br><br>

I won't get deeper into segment registers, how is address of begginning of
segment stored in them (there IS difference), take segment registers as some
kind of black box for now, it works and we can ignore it now.<br><br><br>

<b>3.4. 'org' directive explained</b>

<br>
As your program is loaded, it often needs some external info from program that
runned it. Best example is command line arguments, or it may need know WHO
runned him etc. This value must be, of course, stored in same segment in
program. In .COM files these data (passed to your program by program that
runned you) is stored in first 256 bytes of segment. So your program is loaded
from offset 256.<br><br>

<b>NOTE:</b> 256 byte structure in beginning of .COM file is called "PSP" which
stands for "program segment prefix"<br><br>

Now imagine this .COM program:
<blockquote class="code"><pre>
mov al<font color=#333399>,[</font>variable1<font color=#333399>]</font>
int <font color=#339933>20h</font>
variable1 db <font color=#339933>0</font>
</pre></blockquote>

(notice - no <code>org 256</code> directive). Instruction <code>mov al,
[variable1]</code> takes 3 bytes, <code>int 20h</code> takes 2 bytes, so
<code>variable1</code> will stand for offset 5. So instruction <code>mov
al,[variable1]</code> is <code>mov al,[5]</code>. So this instruction access
6th byte of segment (first byte is at offset 0). But I already told you that
in first 256 bytes of segment are stored some informations, and your program
is loaded behind them, from offset 256. So you don't want to <code>variable1</code>
to be 5, you want it to be 256+5. And this is what <code>org</code> directive
does. It sets "origin" of file addresses. <code>org 256</code> will tell FASM
to add 256 to offset held by every label defined behind this directive (before
next <code>org</code> directive). And this is exactly what we want in .COM
files.<br><br>

So code upwards won't access variable you want, it will access something in
PSP (first 256 bytes of segment). To make it work properly use:
<blockquote class="code"><pre>
org <font color=#339933>256</font>
mov al<font color=#333399>,[</font>variable1<font color=#333399>]</font>
int <font color=#339933>20h</font>
variable1 db <font color=#339933>0</font>
</pre></blockquote><br>

<b>NOTE:</b> <code>org</code> affects labels at time of defintion (for example
at <code>label variable byte</code> or <code>variable db 0</code>), not when
they are used (like at <code>mov ax,[variable]</code>). That means, that if you
change addresses "origin" with <code>org</code> directive after defining some
label, then label will still hold same value before and behind <code>org</code>
directive.  <br><br>

I won't tell you about data contained in PSP, you dont have to care about
them now.

</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -