汇编语言基础从零开始详解【第一话】

汇编发展至今,有两类指令组成:真汇编指令:这些是真指令,每一个都有对应的机器码;伪指令:由汇编编译器翻译成多条真指令,并没有真实对应的机器指令;

实验环境配置:汇编语言基础从零开始详解【第零话】汇编实验环境配置

1. 寄存器

CPU是核心,使用汇编就相当于再软件层面控制CPU,如果想让CPU工作你就必须给他提供指令和数据,指令和数据都放在存储器(内存)里面。在我们看来,指令和数据有着区别,但在机器看来是没有区别的,我们需要利用CPU暂存的寄存器区分开指令和数据。寄存器的作用就相当中转站。以8086PC为例子,有14个寄存器:

  • 通用寄存器:ax,bx,cx,dx
  • 段寄存器:cs,ss,ds,es
  • 地址寄存器:ip,sp,bp
  • 状态字寄存器:psw
  • 索引寄存器:si,di

1.1 通用寄存器

通用寄存器一般是16bit,也就是那些以x结尾的寄存器,我们是可以把一个16b的寄存器拆为两个8b的寄存器使用的,我们可以把一个x寄存器拆为h和l
例如:ax=ah+al

在寄存器里面的数据类型按数据的尺寸进行分类,分为byte(字节)和word(字)
一个word一般是两个byte

指令:
mov 寄存器,寄存器/数据
add 寄存器,寄存器/数据
sub 寄存器,寄存器/数据

【问题1】寄存器的溢出问题
因为一个通用寄存器只有16b,当运算结果长于16b的时候就会溢出。

4b=1个十六进制位=1个十六进制0

执行以下指令:

mov ax,8226h
mov bx,8226h
add ax,bx

我们在VS2019的监视窗口里面可以跟踪到ax最后的数据是044c,但实际上8226+8226=1044c,但因为ax是16b,只能存4个十六进制位。

【问题2】拆分寄存器使用的时候运算也是拆开运算,进位也会可能溢出。
执行以下指令:

mov ax,00aah
mov bx,00a6h
add al,bl

监视ax的变化,会发现最后只有0050。虽然aa+a6=150,但因为是拆分之后运算的,所以进的位不会存到高位的,所以发生溢出。

【问题3】实现自身数值乘2

add self,self

1.2 段寄存器和地址寄存器

在学习段寄存器和地址寄存器之前,我们必须先学习8086CPU是如何读写内存的。如下图:
在这里插入图片描述
小朋友你是否有这样的问号:16+16为毛=20?
实际上,20位的物理地址是由存储硬件本身条件决定的,但是由于CPU手上的位数不够,就只能用两个组合地址来表示一个物理地址了,而地址加法器的公式:

用十进制来看
物理地址=段地址x16+偏移地址

这个16就相当于16进制的数后面多加一个0。

举例
已知段地址1230h,偏移地址0236h
12300+0236=12536

当CPU想要访问内存单元的时候,他需要知道段地址和偏移地址,而我们存放段地址的
用的是段寄存器,存放偏移地址的地址寄存器。

1.2.1 代码指令型地址寄存器:CS和IP

假如我们从内存里面拿指令出来:
最常用的搭配就是CS和IP,(代码型段寄存器和指令指针寄存器)。
在这里插入图片描述
在这里插入图片描述
如何修改段寄存器和指令指针寄存器的内容?
对于通用寄存器,我们修改寄存器的内容用的是mov命令,但是mov缺不能用于CS和IP寄存器,我们使用专门的地址修改命令:jmp。一般来说,一个物理地址的表示:(段地址:偏移地址)。
所以,跳转到一个新的物理地址的指令:

jmp 段地址:偏移地址(同时修改CS和IP)
jmp 偏移地址值(仅修改IP)
jmp 某一寄存器 (取该寄存器的值作为新的地址)好似:mov IP,ax

jmp 2ae3:3
jmp ax

1.2.2 数据型地址寄存器:DS

对于存放指令的内存部位我们使用 CS:IP的形式访问,如果是普通的数据,我们就会利用(数据段地址寄存器)DS:[address]的形式访问。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值