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

📄 chap07.html

📁 vid写的FASM向导
💻 HTML
📖 第 1 页 / 共 2 页
字号:
</pre></blockquote>
will write
<blockquote class="console">
aaaaa
</blockquote>

<b>NOTE:</b> You can optimize that part of code to
<blockquote class="code"><pre>
  org <font color=#339933>256</font>
  mov cx<font color=#333399>,</font><font color=#339933>5</font>
  mov dl<font color=#333399>,<font color=#bb0000>'a'</font></font>
  mov ah<font color=#333399>,</font><font color=#339933>2</font>
here<font color=#333399>:</font>
  int <font color=#339933>21h</font>
  dec cx
  jnz here

  int <font color=#339933>20</font>h
</pre></blockquote>
because value of <code>dl</code> and <code>ah</code> isn't changed anywhere in loop, so
we don't have to set it each time.

<br><br>
Not only <code>add</code> and <code>sub</code> instructions set ZF if result is
zero (and clear it otherwise). All basic arithmetic instructions do this. For
now, you know these arithmetic instructions: <code>add</code>,
<code>sub</code>, <code>and</code>, <code>xor</code> and <code>or</code>. So
afer any of these instruction, ZF tells you if destination (first argument) of
operation holds 0. For example, You can use this behavior to check if value of
register is 0. Before, you would do this with

<blockquote class="code"><pre>
cmp ax<font color=#333399>,</font><font color=#339933>0</font>
jz ax_is_zero
</pre></blockquote>

but you can also use "or" to do this:

<blockquote class="code"><pre>
or ax<font color=#333399>,</font>ax
jz ax_is_zero
</pre></blockquote>

Or won't change <code>ax</code>, because 1 ored with 1 is 1, and 0 ored with 0
is 0. Reread <a href="chap06.html">chapter 6</a> if you don't comprehend that.
Btw, this was used on older computers because such code was faster and is few
bytes smaller than with <code>cmp</code>.

<br><br><br>
<a name="4"></a>
<b>7.4. Carry flag, more binary arithmetic instructions</b>

<br>
I mentioned carry flag a little in connection with overflow. But CF is really general-purpose
flag because it can be tested easily (<code>jc</code>,<code>jnc</code> and few more), and
it's value can be easily set. You will find many more uses of CF later.

<br><br>
How to set CF? There are two instructions for this. <code>stc</code> stays for
"SeT Carry", and so it "sets" carry flag (eg. sets it's value to 1), so
<code>jc</code> jump is taken and <code>jnc</code> is not taken etc etc, you
should understand this aleady. Instruction <code>clc</code> (CLear Carry)
clears CF.

<br><br>
When we know how to work with CF, we can learn about rest of bit arihmetic
operations. First will be <code>shl</code>. It shift bits of register to left,
eg. 0th bit becomes 1st, 1st becomes 2nd etc. Last bit (7th of byte or 15th of
word) is moved to CF. First bit becomes 0. This way (if highest bit wa zero) we
have multiplied the shifted register by 2.

<br><br>
Before shifting: <code>bit7:bit6:bit5:bit4:bit3:bit2:bit1:bit0</code><br>
After shifting: <code>bit6:bit5:bit4:bit3:bit2:bit1:bit0:0</code>,  <code>CF=bit7</code>

<br><br>
To explain why number is multipied by 2. If you remember beginning of 
<a href=chap06.html>chapter 6</a>, you know that number before shifting is
<code>128*bit7 + 64*bit6 + 32*bit5 + 16*bit4 + 8*bit3 + 4*bit2 + 2*bit1 +
bit0</code> so after shifting it becomes <code>128*bit6 + 64*bit5 + 32*bit4 +
16*bit3 + 8*bit2 + 4*bit1 + 2*bit0</code> which is <code>2*(64*bit6 + 32*bit5 +
16*bit4 + 8*bit3 + 4*bit2 + 2*bit1 + bit0)</code>. So if highest bit is zero,
then number is multiplied by two. This way we can easily multiply by powers of
two (2, 2^2=4, 2^3=8, 2^4=16 etc.). Also upper bit is stored in CF so we can
test overflow of mulitplication with <code>jc</code> and <code>jnc</code>

<br><br>
Usually we want to shift more than once (multiply by 4, 8, 16...), so
<code>shl</code> takes second argument, which tells how many times we want to
shift. If we shift by number greater than 1, CF contains 1 if ANY of discarded
bits (x highest bits, where x is value we are shifting by) contained 1. This
way we can still check for overflow. If you are beginner, don't care about
overflow checking too much, you probably won't do it anyway :) (and your
program will probably contains bugs then)

<br><br>
There is one limitation to <code>shl</code> - it's arguments doesn't follow same
rules as other instructions you know (<code>mov</code>,<code>add</code> etc.)
Fisrt argument can be register or memory location, but second can be only numeric
constant or CL register (really, no other).

<br><br>
<b>NOTE:</b> Orignially, at 8086 (that's 086, first of 80x86 series known as
x86, like 286 or 486), there was only <code>shl</code> instruction which could
shift by one, and so for example <code>shl ax,3</code> was compiled into 3
<code>shl</code>s. There also wasn't any shifting by register, you had to make
loop for that. Fortunately 80286 had shifting by constant and by CL so it is
now OK.

<br><br>
That was about shifting left, but there is also other type of shifting, that is
shifting to right. I hope you can now imagine what it does, just few notes to
it. Instruction that performs this is <code>shr</code> (shift right). It's
effect is division by two (or powers of two) without remainder. If we shift
right by two, then remainder (0 or 1) is in CF, otherwise CF beheaves like with
shifting left by number higher than two: If remainder isn't 0 (at least one of
discarded bits was 1) then CF is set, otherwise it is clear.

<br><br><br>
<a name="5"></a>
<b>7.5. Some examples</b>

<br>
At least we are able to make output of number (write number to screen). Too bad
we can only write it in binary :). So here is our task: Write program that
outputs any binary number. For now, we will hardcode number into program, eg.
<code>mov</code>e it into some register as constant. Here is the source.

<blockquote class="code"><pre>
org <font color=#339933>100h</font>

mov bx<font color=#333399>,</font><font color=#339933>65535</font> <font color=#777777>;we store number we want to display in bx</font>
 <font color=#777777>;(because it's not used by DOS services we use)</font>
mov cx<font color=#333399>,</font><font color=#339933>16</font> <font color=#777777>;we are diplaying 16 digits (bits)</font>

<font color=#777777>;display one digit from BX each loop</font>

display_digit<font color=#333399>:</font>
shl bx<font color=#333399>,</font><font color=#339933>1</font>
jc display_one

<font color=#777777>;display '0'</font>
mov ah<font color=#333399>,</font><font color=#339933>2</font>
mov dl<font color=#333399>,<font color=#bb0000>'0'</font></font>
int <font color=#339933>21h</font>
jmp continue

<font color=#777777>;display '1'</font>
display_one<font color=#333399>:</font>
mov ah<font color=#333399>,</font><font color=#339933>2</font>
mov dl<font color=#333399>,<font color=#bb0000>'1'</font></font>
int <font color=#339933>21h</font>

<font color=#777777>;check if we want to continue</font>
continue<font color=#333399>:</font>
dec cx
jnz display_digit

<font color=#777777>;end program</font>
int <font color=#339933>20h</font>
</pre></blockquote>


<br>
I hope you understand this, it's quite simple. Each loop we shift BX register
left by one, so upper bit is moved to CF, then we write '0' or '1' depending 
on value of CF (previously upper bit of number) and continue loop until we write
16 digits (because word has 16 bits).

<br><br>
Example of stepping thru code:<br>
<code>
Start: CF=16, BX=1100101000001011b<br>
Pass1: CX=15, BX=1001010000010110b, CF=1<br>
Pass2: CX=14, BX=0010100000101100b, CF=1<br>
Pass3: CX=13, BX=0101000001011000b, CF=0<br>
...<br>
Pass14: CX=2, BX=1100000000000000b, CF=0<br>
Pass15: CX=1, BX=1000000000000000b, CF=1<br>
Pass16: CX=0, BX=0000000000000000b, CF=1<br>
</code>

<br><br>
In my opinion, if you made it here, with (generaly) understing everything, you
can consider yourself to be more than beginner, congratulations!!! There is
much to learn to become well-armed assembly programmer, but you now have the
sufficent base which you will only extend, with or without use of this
tutorial. (But there are several parts which will be explained further which
are hard to find in any tutorial)

</body>
</html>

⌨️ 快捷键说明

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