汇编语言-----开始到寄存器

2024-06-09 02:20
文章标签 汇编语言 寄存器

本文主要是介绍汇编语言-----开始到寄存器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在汇编语言程序设计时,都将用到debug程序:
R命令:查看,改变CPU中的内容
D命令:查看内存中的内容
E命令:改写内存中的内容
U命令:将内存中的机器指令翻译为汇编指令
T命令:执行一条机器指令
A命令:以汇编的形式在内存中写入一条机器指令。
mov指令,add指令,sub指令:
mov指令的作用是将变量复制,例如:
在编译器中输入a以后,mov (被赋值的变量)(变量的值被利用的变量)
例如:mov ax,bx(意义就是将bx的值赋给ax变量)
add指令,其实大家也能看得出来,就是加法
sub指令就是减法
注意,以上的几个指令都是将左边的为主体,操作右边的事物,最终的结果还是保存在左边。
bl是低位,bh是高位,有进位的话会直接舍掉,不会进到前面一位来。
我们在使用r指令时,会出现很多的寄存器,比如ax,bx,cx,dx等等这一类的寄存器,
每一个寄存器都有自己的含义
mul为乘法
如果是八位乘法,结果默认存放在AX中,八位,在16进制中,最高为FF,如果是16位乘法,高位默认在DX,低位在AX。
div为除法
除数:有8位和16位两种,在一个reg或内存单元中
被除数:默认在AX或DX和AX中,如果除数为8位,被除数则为16位,默认在AX中存放,如果除数为16位,被除数为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
总结除法:8位:AX/BL=AL
16位:DXAX/BX=AX
乘法:ALBL=AX
AX
BX=DXAX;
and和or指令:
与运算和或运算
在debug中,不能直接输入二进制,需要将二进制转化为16进制再进行运算。
左移和右移指令SHL,SHR
将数据左边位,就是将数据最右边添加一个0。
将数据右移一个单位,就是在数据的最左边添加一个0.
循环左移:rol ax,1
循环右移:ror ax,1
再介绍两个指令:
1.inc ax
2.dec ax
就是a++,a–
空指令nop,就是null。
交换指令:
xchg,就是将两个寄存器的数据互换。
取反指令 neg
就是二进制取反,比如ax的值为2,那么二进制为 0000 0010,取反后就为1111 1101,也就是FFFE
段地址X16+偏移地址=物理地址
段地址*16就是将其左移一位
这里解释一下什么是段地址,偏移地址
段地址:在实模式下,内存被划分为许多不同的段(Segment)。每个段都有一个地址,称为段地址。段地址是一个16位的值,它指定了内存中一个段的起始位置。在汇编语言中,通常使用段寄存器(如CS、DS、ES、SS)来存储段地址。
偏移地址:偏移地址是相对于段的起始位置的偏移量。偏移地址是相对于段地址的地址。它指定了在特定段内的位置。偏移地址也是一个16位的值。
DS寄存器就是数据段地址
想要将ax,bx中的数据变成物理地址,需要牢牢抓住ds这个寄存器,因为ds是偏移地址的寄存器,如果ds中的数值为21f0,那么就对应着地址为21f0的这个地址,使用语句 mov ax,[60]就是将21f0这个地址的第60为的值赋给ax.不能直接给ds赋值,需要先将想要的段地址段赋给bx,再使用mov语句赋值给ds。ds是个密集数。
使用add语句也是一样的,可以将段地址中的数据赋值给变量中,例如我使用e 21f0:60这个指令改写了21f0这个偏移地址中的内容,然后将ds的值也改变为21f0,我想将21f0:0060这个地址的内容数据赋值给ax变量,我有两种方式可以实现:1.add ax,[60]
2.mov ax,[60]
cs和ip寄存器是指向代码的寄存器,我们在使用a命令时,可以在内存中缓存代码,这些代码的机器语言是可以通过d命令查看内存读到的,我们也可以根据u命令来查看代码,会发现和我们当时写下的代码是一样的
使用t命令后,ip地址会自加,代表执行了一个语
句了。
当然,在计算机中,代码和数据是不加区分的。
jmp指令:跳转指令
其实我们也可以写出jmp的平替指令,就是将cs和ip指令进行修改,修改到想要执行的而代码的段地址和偏移地址处
其中可以这样理解,jmp bx,就是短地址不变,偏移地址变到了bx所在值的地方
在汇编语言中,CPU提供的栈的机制:
例如:mov ax,0123 //这一段的意思就是将ax的值赋为0123了
然后再 push ax //这个意思就是将ax压栈,那么压栈之后的结果就是将ax的高位01压到栈的底部,然后23这个低位压到01的后面
如果需要弹栈,我们以给ax赋值为例:
e 1000:0000 00.ab 00.cd
mov bx,1000
mov ds,bx

到这个时候,我们使用d 1000:0000指令来看看这一段地址的数据,会发现在1000:0000处,数据显示为 ab,cd
我们接着写指令

mov ax,[0]//这一指令的意思就是将1000这一段指令,由0000这一偏移地址赋值给ax
最后使用r指令来看看ax的值,会发现,ax的值为cdab
说明压栈的时候,是将高位ah赋值给底部,弹栈的时候就是将上面的cd先弹出来赋值给ax的高位

我们来执行一段指令,这个时候,ds是1000H,所以我们把1000H这一段地址当作栈来使用
我们开始指令:
mov ax,0123
push ax //将ax压栈
mov bx,2266
push bx
mov cx,1122
push cx
pop ax
pop bx
pop cx
之后我们使用t指令,将上述指令实现,最后使用r指令来看
会发现 ax=1122,bx=2266,cx=0123
可以很清楚的说明压栈弹栈的过程
高位先压栈,弹栈的时候,先弹给低位,然后是高位
总的来说,就是高位对高位,低位对低位,在dosbox中,我们使用d命令查看内存情况时,右边是高位。
寄存器中,ss:sp在任意时刻都指向栈顶的元素
每次执行一段指令后,ss:sp都会往下弹,此时再弹栈的话,就会弹出指针所指向的元素
如果爆栈后,比如说一个端地址中的某一行偏移地址的元素全弹出后,再执行一次pop指令弹栈,
这个时候,指针会指向下一个偏移地址,不会报错,并没有哪一个寄存器存储的是栈的容量,也不知道栈的空间会有多大,所以只能人为的去小心爆栈。
push 和 pop指令也可以将数据存放在寄存器中。
这个时候我们看ss:sp指针在哪儿,比如我使用mov和add指令将指针指向了1000:0013这个时候就已经指向这儿了,我们再使用push[0]指令,就可以将1000:0000这一地址的数据赋值给1000:0013这个位置了

SI和DI寄存器:寻址寄存器,比如这个指令mov cx,[si]我已经提前将si的值赋为1002了,所以如果赋值的话,就是将2000:1002这一地址的值赋给cx了。所以si和di就是和bx这个寄存器有相似的功能。
所以si和di寄存器使用的目的就是可以将其作为一个偏移地址使用,bx也有相近的功能。在使用的时候,也需要观察一下ds寄存器的位置,ds寄存器对应的位置是当下的段地址。
bp也可以看作是bp的替代,但是两个寄存器又不完全一样。
在使用bp寄存器时,如果没有显性的给出段地址,那么会默认的将ss寄存器所对应的地址作为段地址,也就是栈的位置
如果没有显性的给出段地址:
[bx]对应的就是ds:bx
[bp]对应的就是ss:bp
这里也有区别
1.直接寻址:直接是数字
2.寄存器间接寻址 [bx]
3.寄存器相对寻址:[bx+1]
同等的是[bx].1与上面这个语句的意思是相同的。
同等的也可以是1[bx]
还有[bx][1]
但是不能是[bx][bp]
两个只能用一个,si和di两个也只能用一个。
4.基址变址寻址{bx+si]
5.相对基址变址寻址[bx+si+1]
最后一个寄存器是ES寄存器,就是附加段寄存器

标志寄存器:
ZF标志寄存器表示零标志位
如果结果为0,ZF寄存器就是1,如果结果不为零,ZF=0,是偶数的话PF=1,不是的话,PF=0.、
在dubug中,我们查看的是NZ,ZR(0)

PF标志位:表示的是所有的比特位中1的个数是否位偶数
在debug中,我们看的是PE和PO
PE(1) PO(0)

SF标志位:符号标志位:记录的是在执行相关指令后,结果是否为负。是负数,SF=1,不是,SF=0。
在debug中,看的是pl,pl的意思是正数 ,NG的意思是负数

CF标志位:进位标志位,在mov指令,不会使CF标志位出现变化,add指令时,有可能会发生进位,在debug中,进位为CY,没进位为NC。

OF标志位:溢出标志位,在debug中,如果发生了溢出OV,没有溢出就是NV

这篇关于汇编语言-----开始到寄存器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1043989

相关文章

Modbus初学者教程,第三章:modbus寄存器说明

第三章:modbus寄存器说明 寄存器种类 Modbus协议中一个重要的概念是寄存器,所有的数据均存放于寄存器中。Modbus寄存器是指一块内存区域。Modbus寄存器根据存放的数据类型以及各自读写特性,将寄存器分为4个部分,这4个部分可以连续也可以不连续,由开发者决定。寄存器的意义如下表所示。 Modbus协议定义了设备间的数据传输方式,包括数据格式和通信规则。Modbus寄存器是协议中用

读线圈和离散状态寄存器信息

一.功能码操作类型 二.读线圈状态 需求实例 读取设备地址为 3 的从设备的线圈状态寄存器,线圈地址为 19 到 55(从 0 开始计算)共 37 个状态。 分析:由需求可知读取地址,则功能码是0x01,地址为3即为0x03,线圈地址为19到55则起始地址为19,即0x13,数量为37,即是0x25,查询报表如下所示: 假设从设备的状态值如下: 对应的响应包如下: 使

STM32读写备份寄存器和实时时钟

文章目录 1. 硬件电路 2. RTC操作注意事项 操作步骤 3. 代码实现 3.1 读写备份寄存器 3.1.1 main.c 3.2 实时时钟 3.2.1 MyRTC.c 3.2.2 MyRTC.h 3.2.3 main.c 1. 硬件电路 对于BKP备份寄存器和RTC实时时钟的详细解析可以看下面这篇文章: STM32单片机BKP备份寄存器和RTC实时时钟详解

一文概括:内容可寻址寄存器(CAR)

一、概述         内容可寻址寄存器(Content-Addressable Register,CAR)是一种能够根据内容(数据)而非传统的存储地址来进行数据访问的特殊存储单元。与地址可寻址寄存器不同,内容可寻址寄存器可以通过指定的数据值来查找存储的位置,使其在需要高效数据检索的应用中尤其有用。 二、工作原理         内容可寻址寄存器的操作基于数据内容匹配而非地址访问。其工作过

寄存器和存储器的区别与联系

在计算机系统中,寄存器和存储器是两个重要的概念,它们在数据存储和处理过程中扮演着不同但互补的角色。本文将详细讨论寄存器和存储器的区别与联系。 1. 基本概念 **寄存器(Register)**是一种速度极快的小容量存储单元,通常集成在CPU内部,用于暂存数据和指令。寄存器可以在一个CPU时钟周期内被读取或写入。 **存储器(Memory)**通常指随机存取存储器(RAM),是一种速度较慢但容

74HC595移位寄存器

参考文章 参考文章 1-7,15号端口接8个LED或者8位数码管; 8号口接地; 9号口连接下一个595或者置空; 10号口接vcc; 11号口接D2; 11脚SRCLK移位寄存器时钟输入:当一个新的位数据要进来时,已经进入的位数据就在移位寄存器时钟脉冲的控制下,整体后移,让出位置。 12号口D3; 12脚RCLK存储寄存器:数据从位移寄存器转移到存储寄存器,也是需要时钟脉冲驱动的,这就是12

汇编语言程序设计 - 从键盘接收一个小写字母,然后找出它的前导字符和后续字符,再按顺序显示这三个字符

80x86汇编习题 题目描述:编写程序,从键盘接收一个小写字母,然后找出它的前导字符和后续字符,再按顺序显示这三个字符 思路: 1,用1号功能接收一个字符到VAR,确保在a-z之间 2,先将DL减一,再输出三次DL,DL逐次递增 3,(换行回车,输出提示字符,显示得好看一点。) DATAS SEGMENTTIPS DB 'Please enter a lowercase lette

汇编语言程序设计 - 将BX中的无符号数以八进制形式输出

8086汇编习题 题目描述:将BX中的无符号数以八进制形式输出 思路: 1,往bx写入一个数 2,每三位bit合起来显示一个八进制数,16/3=5余1,所以先处理一位最高位,再循环5次处理 3,用循环移位的方法,先输出第一位(最高位 4,用循环移位的方法,每次移动3位到最右边,将BL复制到DL中操作,按位与最后3位,加上'0'对应的aciil码 5,中断输出DL的内容,继续循环。

《汇编语言程序设计》例子之查找最大数

以下是第5章中讲到的 CMOV 的指令的例子,原来的源码是这样的: # cmovtest.s - An example of the CMOV instructions.section .dataoutput:.asciz "The largest value is %d\n"values:.int 105, 235, 61, 315, 134, 221, 53, 145,

如何访问寄存器

标题 方式一:对地址进行宏定义方式二:用结构体封装寄存器 访问寄存器是CPU执行程序的基础,每种CPU架构都有其特定的寄存器集合和访问方式。 方式一:对地址进行宏定义 #define GPIOA_BASE ((unsigned int)0x48000000)#define GPIOA_ODR (GPIO_BASE + 0X14)//读操作val1 = *(unsign