汇编学习(三)——汇编语言程序入门
一、寻址方式
1、概念:
一条指令由操作码和操作数构成,操作码是系统定义好的符号,执行指定的操作,操作数即是指令的对象,而寻址方式就是操作数的指定方式
- 操作码 目的操作数,源操作数
2、寻址方式的三种情况:
(1)CPU中(2)储存器(3)I/O中
3、寻址方式分类
(1)隐含寻址:
指令中只有操作码没有指定的操作数,但是根据操作码就可确定相应的操作数
- MUL BL;
- DIV BL;
(2)立即寻址:
指令中直接给出要操作的数
- ADD AL,50
立即寻址只能用在源操作数上
(3)寄存器寻址:
A、指令中给出寄存器的名字,寄存器中的内容是要操作的数,这种方式称为寄存器寻址。
B、可以使用寄存器:8个通用16位寄存器(AX,BX,CX,DX,SI,DI,BP,SP),以及8个8位寄存器(AH,AL,BH,BL,CH,CL,DH,DL)
- ADD AL,BL
(4)段寄存器寻址:
A、指令中给出段寄存器的名字,段寄存器中的内容是要操作的数,这种方式称为段寄存器寻址。
B、可以使用段寄存器:4个段寄存器(CS,DS,ES,SS)
C、8086中只有数据传输指令MOV,堆栈操作指令PUSH和POP可以使用段寄存器寻址方式
(5)I/0口寻址
A、操作数在I/O接口中,这种寻址方式为I/O寻址
B、只用使用IN/OUT操作。
C、直接IO寻址:使用一个8位无符号数指定端口号
间接IO寻址:使用一个16位寄存器DX来指定端口号
(6)转移地址的寻址:
指令指针IP会一直指向下一条要执行的命令,所以使用指令转移IP内容,成为转移地址的寻址
(7)储存器操作数的寻址
①概念:
8086CPU有20根地址线,所以储存器每个单元的地址是20位(2进制),称为物理地址,而CPU内部的寄存器都是16位,只用一个寄存器不能完整表示储存器地址,所以拆成2个分量:段地址(CS,DS,ES,SS),偏移地址(BX,BP,SI,DI)
- 物理地址 = 段地址*10H + 偏移地址
②直接寻址
- ADD AL,[Xvar]
将Xvar地址中的内容与AL相加,并储存在AL中;其中Xvar是在数据段中定义的一个变量名
A、直接寻址:要用变量名指定地址
立即寻址:常数作为源操作数
- ADD AL,[20H]
认为是立即寻址
③寄存器间接寻址
A、将储存器的偏移地址存在一个16位寄存器中,然后用方括号中的16位寄存器指定此偏移地址,成为寄存器间接寻址
B、BX,SI,DI搭配DS(数据段)
BP搭配SS(堆栈段)
- ADD AL,[BX]; 从数据段的此地址取数据
- ADD AL,[BP]; 从堆栈段的此地址取数据
④寄存器相对寻址
A、就是在寄存器间接寻址的基础上,使用BX+D(8位或者16位的常数偏移量)作为地址
- ADD AL [SI+5];
- ADD AL [BP-5];
⑤基址变址寻址
A、将一个基址寄存器(BX,BP)与一个变址寄存器(SI,DI)的内容相加作为偏移地址,段寄存器搭配由基址寄存器决定:BX搭配DS,BP搭配SS
B、计算公式:
- 物理地址=DS*10H+BX/DP+SI/DI
C、指令
- ADD AL,[BX+SI]; 只能相加
- ADD AL,[BP-DI]; 不能相减
- ADD AL [BX+BP]; 也不能是两个基址寄存器
- ADD AL,[SI+DI]; 或者是两个变址寻址器
⑥相对基址变址寻址
A、就是在寄存器基址变址寻址的基础上,使用BX+SI+D(8位或者16位的常数偏移量)作为地址
- ADD AL,[BP+BI+5]
- ADD AL,[BP+BI-5]; 同样的,不能有减法
二、数据传送指令
1、通用数据传送指令
- MOV dst,src;
(1)立即数传送给寄存器或储存单元
A、立即数只能作为源操作数
B、若寄存器是16位,立即数可以是16位或8位,若寄存器是8位的,立即数只能是8位的。
C、目的操作数是存储器,而立即数是8位,则存储器必须有类型说明
(2)通用寄存器与存储器之间的传送
若通用寄存器是8位,则按字节传送,若是16位,则按字传送。
(3)两个通用寄存器之间的传送
源和目的必须同为8位或者16位寄存器
(4)段寄存器与通用寄存器或存储器之间的传送
A、程序的一开始,经常需要用立即数对段寄存器赋初值,但是,立即数为源操作数,段寄存器为目的的操作数寻址方式是非法的,所以使用:
- MOV AX,DATA
- MOV DS,AX
B、段寄存器作为源操作数时:DS,SS,ES,CS都可以使用
作为目的操作数:CS不能使用
C、IP不能作为源操作数或者目的操作数
D、两个存储单元之间的传送是允许的,所以
- MOV AX,X1
- MOV X2,AX
2、交换指令:
(1)指令格式
- XCHG dst,src;
(2)操作数不能是立即数、段寄存器、存储器操作数。
(3)操作数的长度要一致
3、堆栈操作指令
(1)入栈指令:
A、指令格式:
- PUSH src
将一个源操作数压入堆栈,具体过程:先将堆栈指针SP减2,然后将源操作数存入堆栈中SP所指的地址.
(2)出栈指令:
- POP src
将堆栈顶部的数据弹出给目的操作数,具体操作:以SS为段地址,SP为偏移地址,将此地址中的数据取出传给目的操作数,然后堆栈指针SP加2
(3)一些注意事项:
A、POP和PUSH的操作数必须是16位的。通用寄存器和存储器皆可。
B、一些错误指令:
- PUSH 1234 不能是立即数
- PUSH AL 不能使用8位寄存器
- PUSH IP 不能使用IP寄存器
- POP 1234H 不能使用立即数
- POP AL 不能使用8位寄存器
- POP CS CS不能作为目的操作数
C、低字节在低地址,高字节在高地址
4、查表指令
(1)指令格式:
- XLAT
- XLAT src_table
又称换码指令,用BX指向数据段中一个表格的首地址,AL为某元素的下标,查表得到此元素的值存入AL中
(2)demo
- MOV BX OFFSET TABLE
- MOV AL,5
- XLAT
5、输入/输出指令
(1)指令格式
(2)一些注意点:
A、操作数必须是累加寄存器AL或者AX;另一个操作数是8位无符号port或者16位的数据寄存器DX,用来指定I/O接口电路中的一个地址
B、地址超8位,只能使用间接寻址。
6、地址传送指令
(1)有效地址传送:
A、指令格式:
- LEA reg16,mem
源操作数必须是存储器操作数,目的操作数必须是16位的通用寄存器,功能是将存储器操作数的偏移地址传送给给一个16通用寄存器.
B、OFFSET:功能是取存储器操作数的偏移地址。
(2)地址指针送寄存器和DS
- LDS reg16,mem32; 等同于 reg16<---[mem32],DS<---[mem32+2]
(3)地址指针送寄存器和ES
- LES reg16,mem32; 等同于 reg16<---[mem32],ES<---[mem32+2]
7、标志位传送指令
(1)标志寄存器送AH
A、指令格式:
- LAHF; 等同于AH<----标志寄存器的低八位
(2)AH送标志寄存器
A、指令格式:
- SAHF; 标志寄存器低8位<------AH
PS:只能对标志寄存器的低八位进行操作
(3)标志寄存器入栈
A、指令格式:
- PUSHF; SP<------SP-2 SS:[SP]<------ 标志寄存器
(4)标志寄存器出栈
A、指令格式:
- POPF; 标志寄存器<-------SS:[SP], SP<----SP+2
三、汇编语言程序结构:
- DATA SEGMENT ;数据段开始
- …… ;伪指令,定义数据段变量
- DATA ENDS ;数据段结束
- EXTRA SEGMENT ;扩展段开始
- …… ;伪指令,定义扩展段变量
- EXTRA ENDS ;扩展段结束
- STACK SEGMENT ;堆栈段开始
- …… ;伪指令,定义数据段变量
- STACK ENDS ;堆栈段结束
- MAC1 MACRO ;宏指令定义开始
- …… ;伪指令或者指令,宏定义体
- ENDM ;宏指令定义结束
- CODE SEGMENT ;代码段开始
- ASSUME CS:CODE,DS:DATA,ES:EXTRA,SS:STACK
- START: ;主程序起始地址定义
- MOV AX,DATA ;寄存器初始化
- MOV DS,AX
- MOV AX,EXTRA
- MOV ES,AX
- MOV AX,STACK
- MOV SS,AX
- …… ;指令
- CALL SUB1 ;调用子程序
- ……; ;指令
- MAC1 ;调用宏指令
- …… ;指令
- MOV AH,4CH ;返回DOS
- INT 21H
- SUB1 PROC ;子程序定义开始
- ……
- RET ;返回主程序
- SUB1 ENDP ;子程序定义结束
- CODE ENDS ;代码段结束
- END START ;结束汇编
1、分段结构
(1)代码段结束处,必须加入如下代码,实现返回系统的功能
- MOV,AH,4CH
- INT 21H
(2)子程序中必须有RET使之能返回主程序
2、语句格式
(1)指令语句:
A、格式:
- 标号:操作码 目的操作数,源操作数;注释
(2)伪指令语句:
A、格式:
- 变量 操作码 操作数,……,操作数;注释
B、作用:
汇编时起到辅助作用,不产生机器码,也称为指示性语句。
(3)宏定义语句
A、格式:
- 标号:宏定义指令名 实际参数;注释
B、使用MACRO伪指令定义了一条宏指令之后,在代码段中就可以用宏指令语句来调用此宏指令。
3、变量和标号:
变量和标号都是来表示存储器中的地址,标号只能在代码段中定义,变量可以在任意段中定义。标量和标号都有段地址、偏移地址和类型三种属性,变量的类型属性有:BYTE,WORD,DWORD几种。标号的类型有NEAR或者FAR两种。
4、操作数、表达式和操作符
(1)算术操作符:+ – * / 和MOD
加减可以对地址进行操作
(2)逻辑操作符:AND,OR,XOR,NOT,SHL(左移),SHR(右移)
和指令操作码方法一致,但只能对数值进行操作,不能对地址进行操作
(3)关系操作符:EQ(相等)、NE(不等)、GT(大于)、LT(小于)、GE(大于等于)、LE(小于等于)
A、用0表示假,用0FFH或者0FFFFH表示真。
B、可以比较数值也可以比较地址
(4)分析操作符:SEG,OFFSET,TYPE,LENGTH和SIZE
SEG | 取段地址 |
OFFSET | 取偏移地址 |
TYPE | 取类型 1:BYTE 2:WORD 4:DWORD |
LENGTH | 取变量中用DUP定义的数据的个数 |
SIZE | LENGTH和TYPE的乘积 |
(5)属性操作符:HIGH、LOW、SHORT、PTR、THIS和段操作符共6个
HIGH | 取高字节 |
LOW | 取低字节 |
SHORT | 段类型 |
PTR | 改变标号 |
THIS | 改变变量类型 |
5、常用伪指令
(1)符号定义伪指令
A、格式:
- 名称 EQU 表达式 ;使用EQU定义的名称可以进行修改
名称 = 表达式 ;不可以进行修改
B、作用:
就是定义个符号常量的作用。
(2)数据定义伪指令
A、格式:
- 变量 伪操作符 表达式,表达式,……;注释
- 变量 伪操作符 重复次数 DUP(表达式,表达式,……);注释
B、说明
①其中变量和注释可有可无,然后定义数据的伪操作符有以下5个:DB(字节),DW(字)、DD(双字)、DQ(8个字节)和DT(10个字节)
②若要定义一组数是相同的,使用第二种方法
③若要预留地址空间,没有初始数值,则数据项可以写为”?“每一个”?“代表一个数据,占用的地址为由伪操作符决定
四、汇编成语上机过程,(使用寻址方式验证代码来书写)
1、DOSBox模拟器初始化
其中g:\汇编目录下有:
2、编辑
键入代码后回车。
- edit xunzhi.asm
得到如上界面,进行书写代码,并保存。
3、汇编
如图键入代码,回车回车回车
这里会显示语法错误信息,如果有错就会报错
3、链接
键入代码回车
没有错误,则进行调试
5、调试
如图键入代码:然后回车就进入调试
(1)键入U回车
A、U命令是反汇编,将内存中的机器码反汇编成指令显示。
B、可能每次不能显示全部指令,所以再U可以继续显示,U0可以返回到代码段的首部
(2)在内存中查看数据段,扩展段和堆栈段中的数据
查看内存中的数据使用命令
- D+地址:0
- D076A:0
再次键入D命令,会继续往下面显示
(3)单步运行程序,查看运行结果
t=0 从第一句开始,按t顺心执行
汇编学习(三)——汇编语言程序入门的更多相关文章
- 汇编语言程序入门实验一:在dos下对用户输入作出应答
汇编语言程序入门实验一:在dos下对用户输入作出应答 1,背景 成功预言了今天要上计算机操作系统上机实验课,昨天预习后,今天的两个上机实验做得很成功.但是也有一些问题.问题1:学校的系统目前是wind ...
- 汇编语言程序入门实验二:在dos下建立子目录操作
汇编语言程序入门实验二:在dos下建立子目录操作 1,背景 在读此文,并读懂前,建议读者先阅读这两篇博客 1,在dos环境下汇编语言程序设计入门(输出hello world)和masm32的下载.安装 ...
- arm汇编学习(三)
一.ndk编译android上运行的c程序 新建个hello目录,底下要有jni目录,下面就是Android.mk文件 1.Android.mk文件内容如下: LOCAL_PATH:= $(call ...
- flask学习(三):flask入门(URL)
一. flask简介 flask是一款非常流行的python web框架,出生于2010年,作者是Armin Ronacher,本来这个项目只是作者在愚人节的一个玩笑,后来由于非常受欢迎,进而成为一个 ...
- 汇编学习-三(VB)
闲来无事做了一下160个crackme,因为是VB程序,所以将得到的一点心得记录如下(OD加载注释) push eax ; Andréna.004018A8 call dword ptr ds:[&l ...
- 小程序入门学习Demo
技术:小程序 概述 适合学习小程序的初级开发人员,入门教程 详细 代码下载:http://www.demodashi.com/demo/14956.html 小程序周边美甲美发预约Demo 代码主 ...
- Python入门基础学习 三
Python入门基础学习 三 数据类型 Python区分整型和浮点型依靠的是小数点,有小数点就是浮点型. e记法:e就是10的意思,是一种科学的计数法,15000=1.5e4 布尔类型是一种特殊的整形 ...
- SCARA——OpenGL入门学习三
OpenGL入门学习[三] 在第二课中,我们学习了如何绘制几何图形,但大家如果多写几个程序,就会发现其实还是有些郁闷之处.例如:点太小,难以看清楚:直线也太细,不舒服:或者想画虚线,但不知道方法只能用 ...
- 天河微信小程序入门《三》:打通任督二脉,前后台互通
原文链接:http://www.wxapp-union.com/forum.php?mod=viewthread&tid=505&extra=page%3D1 天河君在申请到https ...
随机推荐
- ACM/ICPC 之 用双向链表 or 模拟栈 解“栈混洗”问题-火车调度(TSH OJ - Train)
本篇用双向链表和模拟栈混洗过程两种解答方式具体解答“栈混洗”的应用问题 有关栈混洗的定义和解释在此篇:手记-栈与队列相关 列车调度(Train) 描述 某列车调度站的铁道联接结构如Figure 1所示 ...
- 用基础动画实现iOS控件循环旋转
- (void)viewDidLoad { [super viewDidLoad]; UIButton* ag=[[UIButton alloc]initWithFrame:CGRectMake(sc ...
- UIWebView内嵌网页 Xcode7.0以后的用法
UIWebView* webPage=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight-64)]; ...
- Volley与XUtils网络请求使用对比,心得,两者基本使用
之前一直使用的Volley作为网络请求框架,它是Google 在2013年的I/O大会 上,发布的.Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮,同时扩展性很强.在 ...
- 安装Odoo9出现的could not execute command "lessc"问题
解决方案: apt-get install node-less
- IOS- 快速排序,冒泡排序,直接插入排序和折半插入排序,希尔排序,堆排序,直接选择排序
/*******************************快速排序 start**********************************///随即取 当前取第一个,首先找到第一个的位置 ...
- Java IO流题库
一. 填空题 Java IO流可以分为 节点流 和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行. 输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数 ...
- 25个增强iOS应用程序性能的提示和技巧(初级篇)
25个增强iOS应用程序性能的提示和技巧(初级篇) 标签: ios内存管理性能优化 2013-12-13 10:53 916人阅读 评论(0) 收藏 举报 分类: IPhone开发高级系列(34) ...
- 定时器(NSTimer)
iOS中定时器NSTimer的使用 1.初始化 + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget sel ...
- October 6th 2016 Week 41st Thursday
The outer world you see is a reflection of your inner self. 你拥有什么样的内心,你就会看到什么样的世界. And we eventually ...