相关博客:8086汇编基础知识、通用寄存器、CS/IP寄存器与Debug的使用

一、DS寄存器

一个8086CPU寄存器均是16位的,而数据类型有以下两种:
1Byte = 8bit (字节型数据)
1word = 2Byte = 16bit (字型数据)

16位寄存器存储一个字,而在内存中需要两个空间连续的字节存储一个字。(高位地址存放高位数据,低地址存放低位数据)。 任何两个地址连续的内存单元,N号单元与N+1号单元可以看做两个字节单元,也可以看做一个地址为N的字单元中的低字节单元(N)和高字节单元(N+1)。举例如图:

那么CPU如何访问这些地址中的数据呢?我们知道CPU通过CS:IP寄存器获取下一条指令的地址。而要获取数据就需要通过DS寄存器,DS段地址寄存器:存放要访问数据的段地址。

-e 2000:0000 11 22 33 44    //向2000:0000设置初始值
-a
mov bx,2000
mov ds,bx   //设置DS段地址寄存器的值为2000
mov al,[0]
mov cx,[1]  

以上指令将2000:0000地址单元的字节型数据值读取到al(8位)寄存器中。将2000:0001地址单元的字型数据读取到cx(16位)寄存器中。[]表示内存单元,其中的0表示偏移地址,对哪个段偏移的呢?8086CPU会自动读取ds的数据最为内存单元的段地址。最终的寄存器值为:
BX=2000
DS=2000
AX=0011
CX=3322

测试如下:

同样,DS和CS等段地址寄存器都是相通的,不支持将数据直接送进段地址寄存器中,要通过其它寄存器中转,这属于硬件设计问题。

当然,我们将[n]可以存向al、ax,也可以将al、ax存向[n](各种合理组合,都是可以的):

mov [0],al  //al的值存到ds:[0]的地址中
mov [2],ax  //ax字型数据,al存入ds:[2]和ah存入ds:[3]
add ax,[0]  //相加的结果保存到ax中
add [0],ax  //相加的结果保存到ds:[0]与ds:[1]的地址中
sub al,[0]  //相减的结果保存到al中
sub [0],ah  //相减的结果保存到ds:[0]的地址中
...
以下几条指令
mov ds,1000
add ds,ax
sub ds,ax
...等等都是不合理的

在内存中,数据与指令是完全没有区别的,而在寄存器中,数据与指令是有区别的,因为不同寄存器保存的是不同类型数据的地址(CS保存指令数据段地址,DS保存操作数段地址…)而CPU负责读取CS:IP确定下一条指令存放的地址,读取DS得知将要处理的数据的段地址,根据指令中偏移地址找到具体数据。所以说,汇编程序通过CPU读取寄存器寻找指令与数据,进行一系列操作。

二、SS/SP栈段寄存器:

在C、C++、Java…一系列高级语言中,我们都使用过栈这种数据结构,在汇编这种古老的语言中,栈当然也是存在的。那么如何在汇编中使用寄存器描述一个栈空间?就需要用到SS与SP寄存器。对于8086汇编来说,一次入栈/出栈的字节数都是2字节即1字。

push指令 –> ①SP - 2 –> ②将字型数据存放到SS:SP地址中
pop指令 –> ①将SS:SP地址的字型数据取出来 –> ②SP + 2
上面这个步骤就像C中我们入栈前先移动栈顶指针,再入栈。出栈时先取出数据,再将栈顶指针向栈底移动(属于“满栈”(先移动Top再压栈))。

指令使用规则:
push 16bit寄存器/push “DS:[n]”:寄存器可以为 (ax\bx\cx\dx\ds\es\ss\sp…),8位寄存器不可以。(SP-2,从指定寄存器/“DS:[n]”地址中读取数据入栈)
pop 16bit寄存器/pop “DS:[n]”:(从栈中取出数据放到寄存器/“DS:[n]”地址中,SP+2)
(在Debug中“DS:”需要省略,只用一个[n],CPU自动会从DS中读取栈段地址。可以从寄存器或DS:[]地址中读取数据入栈但是不能“push FFFF”将值直接入栈,出栈亦然)

注意:栈底在高内存地址,任意时刻,SS:SP指向栈顶元素(那么SS:SP两个寄存器就类似于一个Top指针),所以说栈在哪里是由SS:SP决定的(给SS:SP初值即为栈底)。但是栈的大小是没有严格界限的,当SP-2<0时,又会从FFFF开始减,但是不保证其权限。可能越界错误,可能不越界错误(不会自动判断栈满/栈空)。而关于栈的越界问题需要程序员自己注意(这个比C更自由,但更不安全)。

eg:
/*通过Debug的-r修改SS:SP*/
-r SS
2000
-r SP
10
/*或者:通过寄存器中转修改SS:SP*/
mov ax,2000
mov ss,ax
mov sp,10   //IP寄存器不能直接用值修改,但是SP寄存器可以//就是指定栈底地址为2000:10,此时SS:SP=2000:0010
mov ax,1234
mov bx,5678
push ax     //SP-2=000E,2000:E与2000:F中分别存放34和12
push bx     //SP-2=000C,2000:C与2000:D中分别存放78和56
pop cx  //出栈CX=5678,SP+2=000E
pop dx  //出栈DX=1234,SP+2=0010

我们将入栈过程分析一下,如图所示:

出栈则是其逆过程,先出值到寄存器中,再移动栈顶指针(修改SS:SP寄存器值)

明白了CS、DS、SS寄存器后我们就可以为数据段(text)、代码段(code)、栈段(stack)总结一下了:

数据段:存放数据的段(段地址在DS中)
代码段:存放代码的段(段地址在CS中)
栈段:存放临时性数据的并且由SS:SP维护的段(段地址在SS中)

三、DS、SS、SP寄存器混合使用:

(例题为王爽老师的《汇编语言》第三章检测点3.2)
将10000H~1001FH中的八个字,逆序复制到20000H~2001FH中,如何用栈做?
法一:
从ds:[]入栈,ds:[]是源(10000H~1000FH),栈是目标(20000H~2000FH)

//设置数据段地址
mov ax,1000H
mov ds,ax   //设置栈段地址
mov ax,2000H
mov ss,ax
mov sp,10H  //从数据段向栈段复制:是从指定数据段(10000H~1000FH)向指定栈段(20000H~2000FH)存放数据
push [0]
push [2]
push [4]
push [6]
push [8]
push [A]
push [C]
push [E]

法二:
出栈至ds:[],栈是源(20000H~2000FH),ds:[]是目标(10000H~1000FH)

//设置数据段地址
mov ax,2000H
mov ds,ax//设置栈段地址
mov ax,1000H
mov ss,ax
mov sp,0H//从栈段向数据段复制:是将指定栈中(10000H~1000FH)值放到指定的数据段中(20000H~2000FH)
pop [E]
pop [C]
pop [A]
pop [8]
pop [6]
pop [4]
pop [2]
pop [0]

混合图解:

法一测试:
先给10000H~1000FH设定初始值:

执行所有出栈指令后,可以看到10000H~1000FH的值被按字(不是安字节)逆序复制到了20000H~2000FH。

8086汇编学习之DS寄存器、SS/SP寄存器相关推荐

  1. 8086汇编学习之[BX],CX寄存器与loop指令,ES寄存器等

    同类学习笔记总结: (一).8086汇编学习之基础知识.通用寄存器.CS/IP寄存器与Debug的使用 (二).8086汇编学习之DS寄存器.SS/SP寄存器 一.汇编程序的基本格式: 1.基本格式与 ...

  2. 8086寄存器学习笔记-SS 寄存器和 SP 寄存器

    SS 寄存器和 SP 寄存器: SS 寄存器:Stack Segment (堆栈段寄存器) SP 寄存器:Stack Pointer(堆栈指针寄存器) 这两个寄存起是为了访问内存用的,SS为段寄存器, ...

  3. 8086汇编学习小记-1

    8086汇编学习小记-1 View Code assume cs : codesg, ds : datasg, ss : stacksgdatasg SEGMENT... datasg ENDSsta ...

  4. 8086汇编学习小记-王爽汇编语言实验12

    8086汇编学习小记-王爽汇编语言实验12 0号中断处理程序,开始安装在0000:0200处的程序最后用死循环导致显示不出'divided error',改成直接退出就正常显示了.注意修改ss,sp之 ...

  5. 栈Stack和段寄存器SS,SP(学习汇编)

    1. 栈有2个基本操作:入栈.出栈 2. 栈顶的元素总是最后入栈,最先出栈:后进先出. 3. 8086CPU提供入栈和出栈的指令,最基本的两个是 PUSH(入栈) 和 POP(出栈) push ax ...

  6. 【汇编语言】栈区与SS:SP寄存器

    汇编语言 - 栈 栈是一块特殊的内存空间,本文涉及的CPU为8086CPU,所有与内存地址有关的数字皆为16进制 前言 栈的运行规律 - 先进后出,后进先出 以下为入栈的过程: 以下是出栈的过程: 以 ...

  7. 8086 汇编寄器基础篇 物理地址- 寻址方式 - 寄存器说明

    基本数据类型 规定 计算机的存是以二进制位表示的信息位数一般是8的倍数   字节 一个字节由8个二进制组成   字符串 是指由字符构成的一个线性数组, 通常每个字符用一个字节表示,但有时可用以字和双字 ...

  8. 汇编学习教程:循环和CX寄存器

    引言 在上面博文中,我们主要学习了BX寄存器配合DS寄存器完成内存访问,同时也探究了Masm编译器面对弱指定和强指定两种情况时所产生的不同编译结果. 我们提到:xx:[idata] 是强指定格式,这种 ...

  9. 汇编学习笔记1 通用寄存器和段寄存器详解

    一.通用寄存器 寄存器         编号(二进制) 编号(十进制)   64位 32位 16位 8位     累加寄存器 RAX EAX AX AL 000 0 计数寄存器 RCX ECX CX ...

最新文章

  1. 28. Leetcode 25. K 个一组翻转链表 (链表-反转链表)
  2. Maven的maven-install-plugin插件详解
  3. 【POJ-3259】 Wormholes(判负环,spfa算法)
  4. 二级省市联动下拉菜单
  5. 从“在winform里打开网页功能”引发的问题探究
  6. Python Chemistry
  7. Cocos Creator学习のTiledMap
  8. Godot Label 节点
  9. win10电脑360调用不到JAVA,win10系统打不开360浏览器快捷方式的修复步骤
  10. 游戏中MD5加密的一些作用
  11. 上海企业英语培训机构排名
  12. 编程数学-∑(求和符号)-Sigma
  13. 超媒体是什么?Hypermedia(一种采用非线性网状结构对块状多媒体信息(包括文本、图像、视频等)进行组织和管理的技术)
  14. 只有程序员能听懂的笑话【关于TCP的链接的笑话】
  15. 数据分析01 - 规范化方法
  16. 基于Arduino的显示测量环境数据设计
  17. 机房集中监控中KVM的五大设计原则是哪些?
  18. 高质量 iOS 博客推荐(iOS界技术大牛)
  19. 计算机上m键mm代表什么意思,M与MM分别代表什么?What does M and MM stand for?
  20. 小米VR一体机开发及apk文件导入

热门文章

  1. 配送中心的现代化物流技术
  2. COBIT4.0简介
  3. 阿里云OSS存储 前端上传 MPS-转码模板 工作流以及媒体Bucket设置流程
  4. 微信小程序 四种弹窗方式
  5. iframe跨域消息传递
  6. matlab页面批量下载,[转载]matlab批量从NOAA网站下载验潮站数据
  7. webstorm解决git冲突
  8. 1.vscode 不能运行Python程序,老是显示无法找到文件
  9. ElasticSearch集群安装教程
  10. Android相机应用