吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 3915|回复: 71

[汇编] 8086汇编-寻址方式和指令集

  [复制链接]
啥都不会 发表于 2022-4-28 17:54 | 显示全部楼层 |阅读模式

前言:

这篇笔记主要学习汇编中的寻址方式和数据传送指令。

笔记中的部分解释是参考了滴水讲师的说法并加了自己的一些理解,如有问题欢迎大家指出。

编程语言:

汇编语言

以下为主题内容:

笔记参考 "杨季文《80x86汇编语言程序设计》"

8086 寻址方式

汇编指令格式:

操作码 操作数1,操作数2

我们执行汇编指令时,其中表示指令中的操作数(需要处理的数据)在哪里的方法,被称为寻址方式。

立即寻址

操作数包含在指令中,它作为指令的一部分,跟在操作码后存放在代码段中,这种操作数被称为立即数。

1

寄存器寻址

操作数在寄存器中,指令中指定了寄存器。

2

由于操作数在寄存器中,不需要通过访问内存(存储器)来取得操作数,所以采用这种寻址方式的指令执行速度较快。

直接寻址

操作数在存储器中,指令直接包含有操作数的有效地址。汇编中使用 [偏移地址] 来表示读取某个偏移地址的操作数。操作数一般存放在数据段中,所以操作数段地址默认在 ds 段中。如果要读取其他段中的操作数,就要加上段超越前缀,如 ES:[1234]

3

寄存器间接寻址

操作数的有效地址在 SI、DI、BX、BP 这四个寄存器之一中,如 mov ax,[si]。一般情况下 SI、DI、BX 作为有效地址使用的是 DS 段寄存器,BP 使用的是 SS 段寄存器。

4

寄存器相对寻址

操作数的有效地址是 "基地址+立即数",使用一个基址寄存器(BX、BP)或变址寄存器(SI、DI)存储基地址。如: mov ax,[bx+4] 还可写成 mov ax,4[bx]

6

基址加变址寻址方式

操作数的有效地址是 "基地址+变址",使用一个基址寄存器(BX、BP)存储基地址和变址寄存器(SI、DI)存储偏移地址。如: mov ax,[bx+si] 还可写成 mov ax,[si][bx]

5

相对基址加变址寻址方式

操作数的有效地址是 "基地址+变址",使用一个基址寄存器(BX、BP)存储基地址;变址寄存器(SI、DI)存储变址;立即数作为固定的偏移量。如: mov ax,[bx+si+1] 还可写成 mov ax,1[si][bx]

7

代码练习

;程序名:addressasm
;功能:7种不同的寻址方式
;=======================================
assume cs:code,ds:data

X = 1234h   ;X EQU 1234h(常量定义)

data segment
;val2 db 1  
;al db ?
val db 1,2,3,4,5,6,7,8,9,0,1,2,5,6
val2 db 12345678h
data ends   

code segment    
start:  
    mov ax,data
    mov ds,ax

    ;立即寻址
    mov ax,X        ;常量 X 编译时被转换成立即数
    mov ax,5678h

    ;寄存器寻址
    mov ax,es
    mov al,dh

    ;直接寻址
    mov ax,[1234h]
    mov ax,es:[1234h]
    mov ax,word ptr val
    mov al,[val+1]

    ;间接寻址方式
    mov si,offset val
    mov bx,[si]

    ;寄存器相对寻址
    mov ax,[si+2]
    mov ax,2[si]

    ;基址加变址寻址方式
    mov bx,4
    mov ax,[si+bx]
    mov ax,[bx][si]
    mov ax,[si][bx]

    lds di,val2        ;LDS 指令的功能是:读取偏移地址处的32位数据,将高 16 位作为段值传送给DS,低 16 位作为偏移地址传给DI.

    ;相对基址加变址寻址方式
    mov bx,offset val
    mov si,0
    mov cx,9      ;表示执行循环次数
L1:
    mov al,[bx+si+1]
    mov al,[bx][si][1]
    mov al,[si][bx][1]
    mov al,[1][si][bx]
    inc si
    loop L1       ;cx减1,并跳转到标号 L1 处,直至cx为0
    ;
    mov ax,4c00h
    int 21h

code ends   
end start

汇编指令

a

b

数据传送指令

数据传送指令可分为:传送指令、交换指令、地址传送指令、堆栈操作指令、标志传送指令、查表指令、输入输出指令。

除了SAHF 和 POPF 指令外,这组指令对标志寄存器没有影响。

传送指令(MOV)

h

CPU 内部寄存器之间的数据传送

i

e

mov si,al       ;错,必须是两个相同大小寄存器才能传送数据
mov ds,es       ;错,源和目的操作数不能同时都是段段寄存器

mov cs,ax       ;把 ax 的值传送给代码段

c

错,能执行通过,但是会产生 int 中断 CDH,并再次跳转到原来的指令处。一直循环执行,导致程序崩溃。

那为什么会出现这种情况能呢?在此之前我们要从计算机的角度去思考程序如何跳转到其他地方并正确执行指令。

首先我们要先确定计算机执行程序指令的规则:程序执行指令是通过 CS:IP 来指定要执行的指令。

其次如果我们是计算机要跳到其他地方执行指令 CS:IP 要符合哪些条件,分别有如下两种情况:

  • 段内执行指令

要在第一个代码段 CS1 中执行指令,此时要执行正确的指令 CS 不能改变,IP 改变。

  • 跨段跳转执行指令

要跳转到第二个代码段 CS2 中执行指令,此时要执行正确的指令 CS 需要改变,IP 也需要改变。

回到刚才执行的指令,我们只改变了 CS 代码段,没有改变 IP。所以导致系统无法找到正确的指令,程序奔溃。

mov ax,ip
mov ip,ax       ;错,指令指针 IP 不能作为源,也不能作为目的

那为什么会这样呢?很简单如果我们是计算机,想要完整的执行程序并实现程序功能,那么我们就必须按照程序的指令顺序一条指令一条指令地来执行,不能在执行过程中随意修改 IP 导致程序输出错误或者崩溃。因此 IP 一定是不能人为修改的(所有的系统都是一样),但是我们可以通过计算机的运行机制,来恶意修改 CS:IP 执行我们的代码,这个就是后面学习的内容了。

立即数传送至通用寄存器或存储单元

f

  • 立即数不能直接传送到段寄存器

在写汇编程序的过程中你会用到很多的寄存器,如果你不小心把立即数传送到段寄存器,或者程序执行过程中修改了段寄存器,那么程序很容易就会崩溃。因为为了保证段寄存器得可控性,所以适当的做一些限制。

  • 立即数永远不能作为目的操作数

寄存器是用来存储数据,然后交给运算器处理的作用。立即数又没有这种功能,肯定会错了。

寄存器与存储器之间的数据传送

g

  • 源操作数和目的操作数的类型要一致
mov ax,word ptr VARB        ;注意当变量类型和寄存器大小不同时,需要我们人为指定告诉计算机我要传送多大的数据到寄存器中。
mov byte ptr VARW,DL        ;同上,两个操作数大小(类型)需要一样
  • 除了串操作指令外,源操作数和目的操作数不能同时是存储器操作数
;错
;1、指令集里面没有这种指令
;2、所有的数据传送指令,两边都不能同时为内存操作数。
mov [si],[di]

具体为什么这样,我也不清楚。暂时先放着,后续等搞懂了再进行补充。

交换指令(XCHG)

j

例:

;交换 op1 和 op2 内存数据
mov bx,op1
xchg bx,op2
mov op1,bx

;类似于
mov ax,op1
mov bx,op2
mov op2,ax
mov op1,bx

XCHG 是复合指令,即使用多个简单的汇编指令组成一个 XCHG 指令。设计复合指令的目的是为了提高程序员编程的效率。

地址传送指令

LEA(Load Effective Address)

k

mov si,offset string    ;offset 是操作符,由编译器识别解析的。在编译过程中 "offset string" 会被替换为 string 变量的偏移地址。
lea si,string           ;lea 是指令,在程序加载到内存后,执行该指令时将 string 变量的偏移地址传送给 si

使用 "offset" 的缺陷:如果 string 变量是局部变量(动态内存分配),在程序执行之前还没有为其分配地址,那么编译器无法取得它的地址肯定会出错。

lea 指令的探究

lea 是用来传送内存地址的,如:lea ax,[1234],本质上是将中括号中的内容 "1234" 传送给 ax。而有效偏移地址范围是在 0000~FFFF 之间,也就是我可以输入其中的任意值。同时在 8086 指令集中,寻址可以使用加法运算。

那么我们是否可以使用 lea 做加法运算呢?

例如:将 "1+2+3" 的值,并传送给AX寄存器。

m

在 x86 计算机中,寻址方式加上了乘法运算,因此可以使用 "lea ax,[1+2*3]" 进行算数运算。

LDS(Load pointer into DS)

n

o

LES(Load pointer into ES)

q

堆栈操作指令

r

s

t

u

标志操作指令

x

y

z

0

从 LDS 开始后面的指令有印象就行。等后面写汇编程序,优化代码时用到的时候再说。

评分

参与人数 15HB +17 THX +7 收起 理由
浅酌◇咖啡 + 1 + 1
消逝的过去 + 1
今日下雨 + 1
后学真 + 1 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
纯英文 + 1
风里去 + 1 [吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩!
fjgh + 2 + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
小菜虫 + 1 [吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意!
于理 + 1 [吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩!
zxjzzh + 2 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
louhaihua + 2 + 1
侠客行 + 1
agan8888 + 1
徐闯 + 1
192939 + 3 + 1

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
fFEH0 发表于 2022-4-28 17:56 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
alYhPoEXkdx 发表于 2022-4-28 17:58 | 显示全部楼层

感谢楼主
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
xcCpAtuOdra 发表于 2022-4-28 18:13 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
IKfTXCG95807 发表于 2022-4-28 18:16 | 显示全部楼层

谢谢分享
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
NhTtVFyi 发表于 2022-4-28 18:17 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
JeBvf102 发表于 2022-4-28 18:19 | 显示全部楼层

威武霸气!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
JbV140 发表于 2022-4-28 18:34 | 显示全部楼层

感谢楼主
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
mbkvpGML4 发表于 2022-4-28 18:39 | 显示全部楼层

谢谢分享
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
pJXAafK 发表于 2022-4-28 18:48 | 显示全部楼层

感谢楼主的热心分享
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层
4层
5层
6层
7层
8层
9层
10层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

快速回复 返回顶部 返回列表