首页 > 其他分享 >chapter6------段间批量数据传送与循环

chapter6------段间批量数据传送与循环

时间:2024-08-03 17:39:10浏览次数:11  
标签:0x07 cx 段间 chapter6 mov 指令 ------ ax bx

跳过非指令的数据区

一般来说,所有处理器指令都应当按顺序存放,在它们中间不允许夹杂非指令的普通数据,因为他们不能作为指令执行,所以要想办法让处理器执行不到这些非指令的内容,比如jmp指令等

在数据声明中使用字面值

  char db 'L', 0x07 \ 
          'a', 0x07

编译阶段会将这些字面值转换成等价的ASCII代码,在NASM中\是续行符,表明下一行应该与当前行合并

段之间的批量数据传送

批量数据传送的指令是movsb 和 movsw,b表示传送以字节为单位,w表示传送以字为单位
这两个指令执行时的前置条件:

  1. DS:SI指向原始数据串ES:DI指向传送的目的地址
  2. 传送次数由CX指定
  3. 传送的方向由标志寄存器的DF位决定,0---正向,1---反向
    - 正向传送,低地址--->高地址,执行cld指令将DF置0
    - 反向传送,高地址--->低地址,执行std指令将DF置1
; 数据
mytext db 'L',0x07,'a',0x07,'b',0x07,'e',0x07,'l',0x07,' ',0x07,'o',0x07,\
          'f',0x07,'f',0x07,'s',0x07,'e',0x07,'t',0x07,':',0x07
number db 0,0,0,0,0
...
...
       ; 批量数据传送的代码
       cld
       mov si,mytext                 ; 设置原数据串的偏移位置     
       mov di,0                      ; 设置目的地址的位置位置
       mov cx,(number-mytext)/2      ; 实际上等于 13,除以2是因为一次传送2个字节
       rep movsw                     ; rep表示重复执行,知道cx为0

使用循环分解数位

loop指令也相当于跳转指令,跳转的是相对量,循环次数由CX指定

并且loop指令是先将CX的值减1,在跳转,若CX的值为0,则退出循环

我们可以将loop指令的循环理解为先执行,后判断

         ;得到标号所代表的偏移地址
         mov ax,number
         
         ;计算各个数位
         mov bx,ax
         mov cx,5                      ;循环次数 
         mov si,10                     ;除数 
  digit: 
         xor dx,dx
         div si
         mov [bx],dl                   ;保存数位
         inc bx                        ; inc 指令表示加1,dec指令表示减1
         loop digit                    ; 跳转到digit标号处继续执行

无符号数和有符号数

  • neg 指令: neg al,表示用0减去al中的值,并将其存储到al中
  • idiv 指令: 与div用法相同,不同的是idiv是用于有符号数的计算,而div用于无符号数的计算(注意有符号数的扩展)
  • 有符号数的扩展:计算机根据最高位来判断有符号数的正负,1位负,0为正,所以当16为有符号数扩展到32位时,正数没什么问题,高16位全是0,负数就要注意了,高16位应该全是1
    • cbw指令,将AL中的有符号数扩展到整个AX(convert byte to word
    • cwd指令,将AX的有符号数扩展到DX:AX(convert word to double word

其他标志位和条件转移指令

  • 标志位
    • 奇偶标志位PF: 运算结果低8位有偶数个1的比特,PF=1,反之,PF=0
    • 进位标志位CF:进行算术操作时,最高位有向前进位或借位时,CF=1.反之,CF=0 (inc指令和dec指令无需记录)
    • 溢出标志位OF:超出目标操作数所能容纳的范围,OF=1,反之,OF=0
  • 条件转移指令
    • 可以根据实际计算结果的标志位进行条件转移
    • cmp指令:用于比较操作数,不同的是cmp仅仅根据比较结果设置标志位,而不保留计算结果,不改变原有的内容
      • cmp 目的操作数, 源操作数,重点关心目的操作数,比如cmp ax, bx,我们关心的是ax的内容是大于bx还是等于bx,bx仅仅是一个测量基准

NASM编译器的$和$$标记

  • $标记:可以看成是当前行行首的标号 (即 当前行的汇编地址)
  • $$标记:代表当前汇编段的起始汇编地址

bochs调试命令

  • n命令:可以跳过循环, 但对条件转移指令造成的循环无效
  • u命令:反汇编,将机器码翻译成可读的汇编指令,u/n 0xb8000表示从0xb8000这个地址开始反汇编n条指令
  • 如何越过条件转移指令构造的特殊循环体:
    • 先用u命令反汇编,找到条件转移指令的下一条指令A
    • 在用b命令对指令A设置断点
    • 在用c命令继续执行到断点处
  • info命令查看标志位
    输入info eflags,会跳出标志位的名称,大写表示为1,小写表示为0

思考题

以下程序会执行多少次

        mov cx, 0
delay:  loop delay

首先loop会将cx的值减1,也就是cx的值为-1,即0xFFFF, 执行1次
然后loop在将cx的值减1,也就是cx的值为-2,即0xFFFE, 执行2次
...
最后.......................cx的值为-65535,即0x1 0000, 舍去最高位1(超出16位), cx的值为0x0000即0,跳出循环,执行65535次

在 x86 的寄存器中,减一操作(SUB 指令)会按照二进制补码进行运算。当寄存器的值为 0 时,再次减一会导致它变成全1的补码形式。因此,CX 寄存器的值会从0xFFFF 到 0x0000

在我想来应该是这样,有错误请大家纠正

完整源码

         ;代码清单6-1
         ;文件名:c06_mbr.asm
         ;文件说明:硬盘主引导扇区代码
         ;创建日期:2011-4-12 22:12 
      
         jmp near start
         
  mytext db 'L',0x07,'a',0x07,'b',0x07,'e',0x07,'l',0x07,' ',0x07,'o',0x07,\
            'f',0x07,'f',0x07,'s',0x07,'e',0x07,'t',0x07,':',0x07
  number db 0,0,0,0,0
  
  start:
         mov ax,0x7c0                  ;设置数据段基地址 
         mov ds,ax
         
         mov ax,0xb800                 ;设置附加段基地址 
         mov es,ax
         
         cld
         mov si,mytext                 
         mov di,0
         mov cx,(number-mytext)/2      ;实际上等于 13
         rep movsw
     
         ;得到标号所代表的偏移地址
         mov ax,number
         
         ;计算各个数位
         mov bx,ax
         mov cx,5                      ;循环次数 
         mov si,10                     ;除数 
  digit: 
         xor dx,dx
         div si
         mov [bx],dl                   ;保存数位
         inc bx 
         loop digit
         
         ;显示各个数位
         mov bx,number 
         mov si,4                      
   show:
         mov al,[bx+si]
         add al,0x30
         mov ah,0x04
         mov [es:di],ax
         add di,2
         dec si
         jns show
         
         mov word [es:di],0x0744

         jmp near $

  times 510-($-$$) db 0
                   db 0x55,0xaa

标签:0x07,cx,段间,chapter6,mov,指令,------,ax,bx
From: https://www.cnblogs.com/winter-z/p/18340845

相关文章

  • Linux
    Linux常用命令Linux仅有一个根目录,用/表示(在windows中是\)ls(ListFiles)列出目录和文件名ls-a-l-hcd(ChangeDirectory)切换目录cd[绝对路径/相对路径]cd.表示切换到当前目录cd..表示返回上一级目录,cd../..返回两级目录cd~表示切换home目录pwd(......
  • python 如何获取导入包中运行脚本的文件名
    我有两个脚本:main.pyimportpackage.pypackage.pyimportosprint(os.path.basename(_file_))我的预期输出是main.py,但我得到package.py那么我如何在包脚本中获取正在运行的脚本的文件名?额外描述:事实是,我在p......
  • 如何在网站上抓取多个需要订购的值
    我正在尝试使用beautifulsoup抓取NHL比赛的结果,但我无法弄清楚如何获取比赛进行的日期以及按顺序排列的结果。比赛日期位于标签下,结果位于“field-content”类中。目前,我可以找到这两个值并将它们放置在自变量中,但我想保留它们在原始网站中出现的顺序并将数据放置在单个变量......
  • 如何修改Excel表格而不丢失扩展名?
    我正在尝试修改Excel文件,其中包含许多VBA操作(不是我创建的)。我温和地尝试修改单个组合框项目。fromopenpyxlimportload_workbook#Loadtheworkbookworkbook=load_workbook('input.xlsx')#Selecttheworksheetworksheet=workbook['Monthly']#Changethe......
  • 2070 欧拉回路--[中等+]
    #include<iostream>usingnamespacestd;//arr记录邻接矩阵dot记录奇点(每个点连接边数量)ans数组存储结果 intarr[105][105],dot[105],n,m,ans[105];//记录奇点intstart[3],sum=0; //x正在到达的结点cnt是数组ans的下标voiddfs(intx,intcnt){   //边......
  • 门控循环单元GRU
    目录一、GRU提出的背景:1.RNN存在的问题:2.GRU的思想:二、更新门和重置门:三、GRU网络架构:1.更新门和重置门如何发挥作用:1.1候选隐藏状态H~t:1.2隐藏状态Ht:2.GRU:四、训练过程举例******:五、预测过程举例******:六、底层源码:七、Pytorch版代码:一、GRU提出的背景:1.RNN存......
  • Python+Pycharm下载安装教程,基础知识(详细教程)
    这是一篇针对初学者的 Python 基础教程,只要你认真阅读,花费30分钟即可快速了解Python。这篇Python入门教程讲解的知识点包括:Python编程环境的搭建、Python基本操作入门、Python数据类型、Python语句和函数。Python环境下载和配置根据Windows版本(64位/32位)从P......
  • 命名空间的彼此调用
    题目:创建一个控制台应用程序,建立一个命名空间MR.Data,在其中有一个类Modle,在项目中使用using指令引入命名空间MR.Data,然后再命名空间MR.View中即可实例化命名空间MR.Data中的类Modle,最后调用此类中的GetData()方法,代码如下: usingSystem;usingSystem.Collectio......
  • GROUP BY 和 HAVING 子句(看完就会)
    GROUPBY 和 HAVING 子句用于对查询结果进行分组和过滤,它们通常一起使用,但也可以单独使用。GROUPBY子句:GROUPBY 子句用于将查询结果根据一个或多个列进行分组。它将具有相同分组列值的行组合在一起,形成一个组。GROUPBY 子句通常与聚合函数(如 SUM、AVG、COUNT、MAX......
  • weapp.qrcode.esm.js
    /***weapp.qrcode.jsv1.1.5*/varhasOwn=Object.prototype.hasOwnProperty,toStr=Object.prototype.toString,defineProperty=Object.defineProperty,gOPD=Object.getOwnPropertyDescriptor,isArray=function(t){return"function"==typeofArray.isArray?Ar......