汇编语言学习
<h1 id="汇编语言学习">汇编语言学习</h1><h3 id="1基础知识">1、基础知识</h3>
<p>这部分内容之前就有在电子书上学习过,趁着寒假买了本二手的《汇编语言》 <s>(二手就是香)</s>结果发现好像在纸质书上学习比在电子书上学习更清楚。。</p>
<p>CPU 与外部器件进行以下三种信息交互</p>
<ul>
<li>存储单元的的地址(地址信息)</li>
<li>器件选择,读或写的命令(控制信息)</li>
<li>读或写的数据(数据信息)</li>
</ul>
<p>以及与其他芯片连接的导线用于传数据</p>
<ul>
<li>地址线(寻址)</li>
<li>数据线 (数据)</li>
<li>控制线 (指令)</li>
</ul>
<p>然后有一个之前觉得挺新的地方 ,就是内存地址中虽然我们看上去各个存储器是分开的,但是在CPU看来地址是连着的</p>
<hr>
<h3 id="2寄存器">2、寄存器</h3>
<ul>
<li>运算器:负责进行信息处理</li>
<li>寄存器:负责进行信息存储</li>
<li>控制器:控制各个器件进行工作</li>
<li>内部总线:连接各种器件,在它们之间进行数据传送</li>
</ul>
<p>8086cpu寄存器都是16位,AX、BX、CX、DX通常存一般性数据 16位寄存器只能存放4位十六进制数据 寄存器可分为两个8位寄存器AH和AL(命名一次类推)</p>
<p>16位结构CPU具有以下方面的结构特点</p>
<ul>
<li>运算器一次最多可以处理16位数据(十进制65535)</li>
<li>寄存器的最大宽度为16位</li>
<li>寄存器和运算器之间的通路为16位</li>
</ul>
<p>段地址与偏移地址的概念</p>
<p>在CPU中因为CPU本身结构问题,一次性处理、传输、展示存储的地址为16位,故提供两个地址,一个段地址,一个偏移地址。通过将段地址*16+偏移地址来实现。</p>
<p>段寄存器 CS、DS、SS、ES</p>
<p>CS 代码段寄存器 IP为指令指针寄存器 <img src="https://img-blog.csdnimg.cn/20190321105503491.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5NjU0MTI3,size_16,color_FFFFFF,t_70" alt="img" loading="lazy"></p>
<p>通过地址加法器将CS和IP的指令处理 经地址总线对内存访问,对内存中的存放的机器指令通过数据总线传递至CPU执行</p>
<p>DS寄存器, 用来存放要访问数据的段地址</p>
<pre><code class="language-assembly">mov指令可以读取内存单元的内容 通过
mov al,实现,其中表示偏移地址 指令执行时,自动取DS寄存器中的数据作为段地址
</code></pre>
<p>然后DS无法直接通过<code> mov ds 1000H</code>实现将段地址数据直接送入DS 而是只能通过中转寄存器实现</p>
<p>任何两个地址连续的内存单元,可以将它们看成两个内存单元,也可看成一个地址为N的子单元中的高位字节单元和地位字节单元</p>
<p>mov指令可以有一下几种形式</p>
<pre><code class="language-assembly">mov指令可以有以下几种形式
mov 寄存器,数据
mov 寄存器,寄存器
mov 寄存器,内存单元
mov 内存单元,寄存器
mov 段寄存器,寄存器
mov 寄存器,段寄存器
</code></pre>
<p>表示一个编译地址为address的内存单元</p>
<p>在内存和寄存器之间传送字形数据的时候,搞地质单元和高8位寄存器、低地址单元和低8位寄存器相对应</p>
<h5 id="栈一个有意思的话题">栈(一个有意思的话题)</h5>
<p>push 和pop 指令</p>
<pre><code class="language-assembly">push 和 pop 指令
push ax 将ax的数据压入栈中
pop ax 从栈顶取出数据赋值于ax
</code></pre>
<p>段寄存器SS和寄存器SP</p>
<p>栈顶的段地址存放在SS中,偏移地址存放在SP中。任意时刻,SS:SP指向栈顶元素。push和pop指令执行时,CPU从SS和SP中得到栈顶的地址</p>
<p>push ax 执行时 操作以下两步</p>
<ol>
<li>SP=SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶;</li>
<li>想ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶</li>
</ol>
<p>入栈时,栈顶从高地址向低地址增长。</p>
<p><img src="https://img-blog.csdnimg.cn/20190321113400430.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5NjU0MTI3,size_16,color_FFFFFF,t_70" alt="img" loading="lazy"></p>
<p>EAX、ECX、EDX、EBX:為ax,bx,cx,dx的延伸,各為32位元<br>
ESI、EDI、ESP、EBP:為SI,di,sp,bp的延伸,32位元CPU中的各个部件用于不同的作用</p>
<p>BX、SI、DI、DP可以用在 [..]进行内存单元寻址、</p>
<p><code> X ptr </code>指明内存单元的长度,X可为word(字)或byte(字节)</p>
<h3 id="程序编译">程序编译</h3>
<p>编程 -> 编译 -> test.obj-> 连接 -> text.exe -> 加载 -> 内存中的程序 -> 运行</p>
<h3 id="call-和-ret指令">CALL 和 RET指令</h3>
<p>ret指令 相当于 pop IP</p>
<p>call指令</p>
<ol>
<li>将当前的IP或CS和IP压入栈中</li>
<li>转移</li>
</ol>
<p>call 标号 将当前的IP压栈中 团岛标号处执行指令</p>
<h3 id="标志寄存器">标志寄存器</h3>
<ol>
<li>存储相关指令的某些执行结构</li>
<li>用来为CPU执行相关指令提供行为依据</li>
<li>用来控制CPU的相关工作方式</li>
</ol>
<p><code>cmp</code>指令 比较指令 通过比较改变一些标志寄存器的值</p>
<pre><code class="language-assembly">cmp ax bx 比较ax和bx的值
zf=1 说明 ax=bx
zf=0 说明 ax≠bx
cf=1 说明 ax<bx
cf=0 说明 ax>=bx
cf=0且zf=0 ax>bx
cf=1或zf=1 ax<=bx
jz指令 当zf=1时跳转
jnz指令 当zf=0时跳转
jge 大于转移指令
</code></pre>
<p>IP寄存器 为指令寄存器</p>
<hr>
<h4 id="一些指令">一些指令</h4>
<pre><code class="language-assembly">mov 传送指令 可理解为赋值
add 加法指令
sub 减法指令
jmp 修改CS IP寄存器内容 即修改段地址和偏移地址
jmp 段地址:偏移地址
jmp 某一合法寄存器 功能 用寄存器的值修改IP
and 与指令
or 或指令
div指令 除法 默认AX 或 DX
div reg
div 内存单元
后为除数
jmp short 转到标号处执行指令 转移结束后CS:IP指向标号处的指令
inc 算数运算指令,起到+1作用
mul 乘法指令 同div 8位默认AL 16位默认 reg或内存字单元
cmp指令 比较
MOVSX指令 带符号传送例如:
1.
MOV BL,80H
MOVSX AX,BL
运行完以上汇编语句之后,AX的值为FF80H。由于BL为80H=1000 0000,最高位也即符号位为1,在进行带符号扩展时,其扩展的高8位均为1,故赋值AX为1111 1111 1000 0000,即AX=FF80H。
2.mov CL, 50H
MOVSX AX, CL
50H=0101 0000,最高位为0,则AX为0000 0000 0101 0000
结果AX = 50H
</code></pre><br><br>
来源:https://www.cnblogs.com/fallrain/p/17034994.html
頁:
[1]