提笔画夕阳 發表於 2023-8-2 14:31:00

汇编语言初识

<h1 id="汇编语言初识-8086">汇编语言初识 8086</h1>
<blockquote>
<p>所有的编程语言都是一种解决问题的方法如果说<br>
java,C++,go,python之类的编程语言是<strong>面向对象的编程语言</strong><br>
C,Pasical之类的编程语言是<strong>面向过程的编程语言</strong><br>
那么像汇编这样的底层编程语言,应该就是所谓的<strong>面向CPU的编程语言</strong><br>
因为它从头到尾都是和<strong>CPU</strong>在打交道</p>
</blockquote>
<h2 id="万物皆内存">万物皆内存</h2>
<p>在计算机中所有的<strong>IO设备</strong>, 包括硬盘、内存、显卡, 它们在CPU看来都是在一个逻辑内里面, 只是分配在不同的段, 有着不同的内存地址而已. 所以本质上他们都可以抽象成内存空间的一部分.</p>
<h2 id="计算机的三条生命线">计算机的三条生命线</h2>
<ol>
<li>地址线: 传达要访问内存空间的地址</li>
<li>数据线: CPU和内存之间传递数据的桥梁</li>
<li>控制线: CPU发号施令的号旗</li>
</ol>
<p>其中每一条线都有着不同的宽度, 它们的宽度决定了传送数据量的多少.</p>
<p>我们都知道一个导线可以表达一个0或者1, 两根导线就可以通过二进制的方式表达两位二进制数.</p>
<p>当然上面的三条线不是真的就三条, 它们本身就一类线的总称, 因为总不能就一条线就可以传递地址或者数据信息吧!</p>
<h2 id="寄存器">寄存器</h2>
<p>AX, BX, CX, DX这四个是通用寄存器, 其中可以保存一个字的大小(由两个内存单元组成)</p>
<p>其中它们都可以拆分使用, 比如AX可以拆分成</p>
<p>AL和AH 分别表示AX低8位和高8位.</p>
<p>CS, SS, DS这三个是段寄存器, 和通用寄存器的大小一样.</p>
<p>IP, SP就是类似指针一样的寄存器, 大小也和通用寄存器一样.</p>
<h2 id="最常见的汇编命令">最常见的汇编命令</h2>
<pre><code class="language-asm">mov 目标,源
add 目标,参加计算的第二个数
sub 目标,参加计算的第二个数
</code></pre>
<h2 id="地址计算">地址计算</h2>
<p>地址 = 段地址 * 16 + 偏移地址</p>
<p>所以地址常用 <code>段地址:偏移地址</code> 来表示, 例如 <code>2000:0003</code></p>
<p>段寄存器一般用于保存<strong>段地址</strong></p>
<p>IP, SP这种类似指针的, 常用于表示<strong>偏移地址</strong></p>
<h2 id="常见的程序段">常见的程序段</h2>
<h3 id="代码段-cs-code-segment">代码段 CS (code segment)</h3>
<blockquote>
<p>这个内存段主要存储需要执行的代码</p>
</blockquote>
<p>CPU会自动将CS存储的段地址和IP存储的偏移量计算出来的地址作为当前需要执行指令的地址.<br>
要想在程序中实现更改CS和IP</p>
<p>可以使用</p>
<pre><code class="language-asm">jmp 2000:0003

; &lt;=&gt;

mov ax,2000H
mov cs,ax
mov ip,0003H

; 常量存储的位置不太一样不能直接使用 mov cs,2000
</code></pre>
<p>每次执行完一条语句, IP会自动移动到下一个</p>
<h3 id="数据段-ds-data-segment">数据段 DS (data segment)</h3>
<p>和之前的代码段有点不太一样, 数据段没有专门用于存储偏移地址的寄存器</p>
<p>只有对应的段寄存器</p>
<pre><code class="language-asm">mov ax,
; 将cs:0000位置数据放到ax
mov ,ax
; 将ax的数据放到cs:0000
</code></pre>
<h3 id="堆栈段-ss-stack-segment">堆栈段 SS (stack segment)</h3>
<p>存储堆栈(stack)数据</p>
<p>SS作为段寄存器<br>
SP作为存储偏移地址的寄存器</p>
<pre><code class="language-asm">push ax
; 入栈, 将ax的数据存入
pop ax
; 出栈, 将弹出的数据存入ax
</code></pre>
<p>CPU执行的时候不会执行任何检测, 要注意是否超出了堆栈的范围<br>
SP会自动进行加减</p>
<h2 id="一个简单的汇编程序">一个简单的汇编程序</h2>
<pre><code class="language-asm">assume cs:codesg

codesg segment

    mov ax,0123H
    mov bx,0456H
    add ax,bx
    add ax,ax

    ; 下面两行是dos退出程序
    mov ax,4c00H
    int 21H

codesg ends

end
</code></pre>
<p><code>assume</code>是伪指令就是用于定义一个段的<br>
<code>segment</code>和<code>ends</code>标记段的开始和结束<br>
<code>end</code>表示程序的结束</p>
<h3 id="tip">tip</h3>
<p>如果需要清零</p>
<pre><code class="language-asm">mov ax,0
sub ax,ax; 字节数更少
</code></pre><br><br>
来源:https://www.cnblogs.com/JacekYang/p/17600586.html
頁: [1]
查看完整版本: 汇编语言初识