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

一、汇编程序的基本格式:

1、基本格式与解析:

assume cs:codeseg   //assume假设CS寄存器与codeseg段有关联,codeseg段本就是代码段codeseg segment //段开始,codeseg为段名,可随意命名只要不和伪指令、指令等冲突即可mov ax,4C00Hint 21Hcodeseg ends    //段结束end //程序结束标志

以上格式中assume、segment、ends、end均为伪指令,由编译器识别翻译。assume的关联并非必须。

    mov ax,4C00Hint 21H

而这两条指令的功能就是实现程序返回,在DOS中如果是command将可执行程序加载入内存,command就设置CPU的CS:IP指向程序的第一条指令,及程序的入口,当程序从入口开始执行完毕以后,“mov ax,4C00H”、“int 21H”看来那个条指令执行后返回到command中,CPU则继续执行command,如果是Debug将可执行程序加载进内存中,则返回后回到Debug(类似于在Shell中运行的子进程(”main(){return 0;})运行完毕会返回shell,shell则继续运行。只不过DOS是单进程,而Linux的Shell是时间片轮转多进程)。

2、注意问题:

(1)不允许操作数以字母开头:
在Debug中一行一行指令输入时,我们可以以字母开头,但是在编辑器编辑、MASM编译、LINK连接时,就不能以字母开头,否则会报未定义错误,如果遇到以字母开头的,在其前面加一个0即可。
eg:

mov ax,B810H    //(×)
mov ax,47120    //(√),B810H的十进制
mov ax,0B810H   //(√),十六进制修改(修正)
mov al,E7H  //(×)
mov al,0E7H //(√)

关于以字母开头会提示错误的测试如下:

(2)-g cs:ip、-g ip 快速执行多行
-g ip 省略cs,默认去ds寄存器中找。

//eg:    这是编译过程中生成的“.lst”文件中的一部分assume cs:codeseg 0000                 codeseg segment 037F:0000  B8 1000           mov ax,1000H 037F:0003  8E D8             mov ds,ax 037F:0005  BB 0000           mov bx,0 037F:0008  8B 07             mov ax,ds:[bx] 037F:000A  BB 0002           mov bx,2 037F:000D  8B 07             mov ax,ds:[bx] 037F:000F  BB 0004           mov bx,4 037F:0012  8B 07             mov ax,ds:[bx] 037F:0014  BB 0006           mov bx,6 037F:0017  8B 07             mov ax,ds:[bx] 037F:0019  BB 0008           mov bx,8 037F:001C  8B 07             mov ax,ds:[bx] 037F:001E  BB 000A           mov bx,10 037F:0021  8B 07             mov ax,ds:[bx] 037F:0023  B8 4C00           mov ax,4C00H 037F:0026  CD 21             int 21H 037F:0028                codeseg ends end
//debug dabx.exe
//直接-g 000F
//将000F之前的运行完停到"mov bx,4"这一行等待运行

上面这段代码编译运行前:

;-d 2000:1000
;00 00 00 00 00 00 00 00--00 00 00 00 00 00 00 00

编译->连接->装载->运行后,结果为:

;-d 2000:1000
;BE 00 EE 00 EE EE EE 00--00 00 00 00 00 00 00 00

(3)、用[bx]代替[n]:
在上面我们已经用到[bx]了。至于为什么要用[bx]代替[n],同样是因为在Debug中会自动识别为ds:[n]段地址+偏移地址的格式,但是在编辑器中编辑并通过masm编译后,这种[n]形式的都会被编译器解析为值,eg:mov ax,[2]会被解析为mov ax,2,但是并不是说必须用[bx]的形式,只是[n]的形式必须配合”段地址寄存器:[n]”的形式一起使用(“这里的不能字母开头”、“[bx]代替[n]”等问题都是Debug与MASM对指令的不同处理方式引起的)。

mov ax,[0]  //对MASM来说错误
mov ax,ds:[0]   //正确
mov ax,ds:[bx]  //正确
mov ax,[bx] //正确

3、程序加载:

编译->连接->装载(加载)->运行的过程,我们说说程序在内存中的装载情况:

,测试如下:

二、loop指令、CX寄存器等:

1、简介:

在C语言中,我们使用过goto语句:

loop_one:int x = 5;...goto loop_one;

而在汇编中的循环(loop)与goto语句及其相似,其格式为:

loop_one:mov ax,5...loop loop_one

我们C中goto循环何时结束的条件一般在if..else判断中,而汇编则是将循环结束条件放在了CX寄存器中。给CX一个初始值(循环次数),当loop指令中标号(如:loop_one)所标识的地址被再次访问,CX的值减去1(即loop执行一次,CX值自减1)。当CX的值为0时结束循环,执行loop指令的下一条指令。loop_one其实就是个地址,loop loop_one就是跳跃到loop_one所标识的地址去(IP寄存器修改为loop_one的地址),从该地址继续解析指令并执行。loop指令的循环形式像do{}while();而不像while(){},因为loop至少会执行一次。那么CX初始化为0时,先减到FFFF再判断,而不是直接判断等于0退出循环。并且这是倒计时式的循环,不是计数式的循环。
(知识点:在用Debug的-p调试时可以不进入循环/call调中去逐句执行。-p:特点是当遇到int中断程序时,会一次性将调用的中断程序执行完;而-t:的特点是当遇到int中断程序时会追踪到调用的中断程序里面去。像loop、call、int 21H等都属于int中断,所以通常会用到-p而不是-t)

2、应用:

例一:计算FFFF:0~FFFF:F的字节型数据的和,结果保存到DX中:

assume cs:codesegcodeseg segment;设置ds寄存器为FFFFHmov bx,0mov ax,0FFFFHmov ds,axmov dx,0        ;初始偏移地址为0mov cx,16       ;FFFF:0~FFFF:F共16个字节,循环16次mov ax,0        ;字节型数据,需要8位寄存器,但是8位可能累加时溢出,必须用16位,所以高位必须清零,之后向AL存数据,所以只需清零一次addNumber:mov al,ds:[bx]  ;字节型数据,需要8位寄存器add dx,ax       ;累加inc bx          ;inc指令将bx的值自加1,即偏移地址增大一个字节loop addNumber  ;条件(CX)减1mov ax,4C00Hint 21Hcodeseg endsend

测试结果:

2、将FFFF:0~FFFF:F的数据复制到0:200~020F中:

assume cs:codesegcodeseg segmentmov cx,16mov bx,0;由于只用一个ds数据段地址寄存器,而需要在两段数据段之间循环操作,就需要用中间寄存器先保存被复制的对象,然后修改ds寄存器,最后将中间寄存器中的一个字节mov到目标地址中copyNumber:mov ax,0FFFFHmov ds,axmov al,ds:[bx]  ;保存到中间寄存器mov ax,0020H    ;修改ds寄存器,0020*10:0==0:200mov ds,axmov ds:[bx],al  ;中间寄存器转移inc bx  ;操作下一个字节loop copyNumbermov ax,4C00Hint 21Hcodeseg endsend

三、ES寄存器:

由于上例题中,用一个ds寄存器在两段地之间来回修改,使得指令数随着循环次数增大而成倍增加,那么我们是否可以借用其它段地址寄存器(cs:[bx]、ss:[bx]、es:[bx]来优化)呢?但是cs和ss都已有他用,只有ES空闲,ES寄存器也是一个段地址寄存器,我们可以用ES段地址寄存器对上例进行优化:
DS:数据从哪里来
ES:数据到哪里去
当然ES和DS在下例中可以替换位置,但是注意:ds可以不写成ds:[bx]的形式,因为[bx]默认是ds:[bx],而ES就必须写成es:[bx],否协会被解析为ds:[bx]。

assume cs:codesegcodeseg segmentmov cx,16mov bx,0mov ax,0FFFFH  ;ds寄存器存储被复制者段地址mov ds,axmov ax,0020H  ;es存放目标段地址mov es,ax;用ES寄存器优化:copyNumber:mov dl,ds:[bx]mov es:[bx],dl  inc bxloop copyNumbermov ax,4C00Hint 21Hcodeseg endsend

测试结果:

还有一点问题:由于汇编是直接对物理内存进行操作,所以不安全的内存操作很可能发生,为了避免使用已经有数据的内存,我们要尽量在0:200~0:2FF的256个字节中进行编程(因为DOS以及其他合法程序一般会使用该段空间)。

8086汇编学习之[BX],CX寄存器与loop指令,ES寄存器等相关推荐

  1. 8086汇编学习小记-1

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

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

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

  3. 8086汇编学习之DS寄存器、SS/SP寄存器

    相关博客:8086汇编基础知识.通用寄存器.CS/IP寄存器与Debug的使用 一.DS寄存器 一个8086CPU寄存器均是16位的,而数据类型有以下两种: 1Byte = 8bit (字节型数据) ...

  4. 汇编(8086cpu): AX,BX,CX,DX寄存器

    AX,BX,CX,DX寄存器这四个寄存器也被称为通用寄存器.一般用来存放数据,一个寄存器可以存放16bit,也就是2bytes. 所以也被称为16位寄存器. 什么特殊的地方导致这四个寄存器和其他寄存器 ...

  5. [从零学习汇编语言] - BX寄存器与loop指令

    文章目录 前言 一. Bx寄存器与[偏移地址] 二. loop指令与jmp指令 1. jmp指令 2. loop指令 三. 一些奇奇怪怪的注意点 1. 汇编源程序的数字问题 2. Debug和Masm ...

  6. 8086汇编学习笔记9-中断

    中断信号可以来自CPU内部或外部. 一. 8086CPU内部中断信号有 (1) 除法错误 (2) 单步执行 (3) 执行into指令 (4) 执行int指令 1. 中断码 8086用一个字节来描述中断 ...

  7. 8086汇编学习笔记10-端口

    8086CPU有两种地址空间,一是内存地址空间,二是端口地址空间,访问端口只能用in和out指令,分别用于从端口读数据和往端口写数据,CPU最多可以定位64KB个不同的端口,端口地址范围为0-6553 ...

  8. 汇编学习之一: jge jnb 跳转指令 /*for 语句代码的汇编实现*/

    JNB al, bl  :al里的内容不等于bl时跳转 JBE al, bl :al里的内容小于或等于bl时跳转 :同理,JGB是大于或等于,JLE是小于或等于 :A(above)大于,B(below ...

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

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

最新文章

  1. css3关键帧动画以及兼容性策略
  2. cNoteReadFile_C语言读取文件内容
  3. iOS开发异常错误总结之——wait_fences: failed to receive reply: 10004003
  4. 概率论与数理统计の笔记
  5. C# IL DASM 使用
  6. 【常见笔试面试算法题12续集一】动态规划算法案例1台阶问题练习题
  7. 设计模式之观察者模式在Listview中的应用
  8. Spring Boot学习笔记:Spring Boot的Web功能
  9. http 访问mysql数据库_04.Http协议之GET请求与访问MySQL数据库
  10. Zend 创始人提议创建 PHP 方言,暂命名为 P++
  11. java的list和数组谁高效_java 中ArrayList与LinkedList性能比较
  12. Java CXF介绍与实例
  13. android 自动打包工具,AutopackingAndroid
  14. PTA—念数字(C语言)两种方法
  15. python pickle模块详解
  16. 商业数据可视化分析工具
  17. 国内商务邮箱品牌——TOM企业邮箱
  18. 理解virt、res、shr之间的关系(linux系统篇)
  19. 苹果xsmax怎么开机_苹果xsmax触屏不灵敏,xsmax触屏失灵怎么回事
  20. chrome网页加载慢问题

热门文章

  1. 那些你觉得堪称神兵利器的 Chrome 插件
  2. JavaScript高级程序设计(第4版)学习随笔【第八章】
  3. DBL_EPSILON和 FLT_EPSILON的用法
  4. matlab 工业相机 曝光时间_工业相机的曝光、曝光时间、快门、增益
  5. TIM学习文档22-- 账户分配
  6. 国内外Unity视频学习网站大全
  7. 面向对象三大基本特性
  8. 随身系统veket linux v3.11简体中文免费版,veket|veket linux上网本操作系统 v5.30 简体中文正式版 - 今朝下载...
  9. linux驱动调试技巧:灌寄存器---------以mma7660为例
  10. Ubuntu 下软件列表