在8086CPU中只有 bx、si、di、和bp可以使用[…]来进行寻址比如;

mov ax,[bx]
mov ax,[bx+si]
mov ax,[bx+di]
mov ax,[bp]
mov ax,[bp+si]
mov ax,[bp+di]

都是正确的
但是下面的指令都是错误的:

mov ax,[cx]
mov ax,[ax]
mov ax,[dx]
mov ax,[ds]

但是这四个也不是随便使用的,必须有相应的搭配才能使用
只有四种组合:bx和si,bx和di,bp和si,bp和di
如下下面的是错误的

mov ax,[bx+bp]
mov ax,[si+di]

只要在[…]使用了bp,而指令中没有西显性的给出段地址,段地址就默认在ss中。比如如下的指令。

mov ax,[bp]    ;含义:(ax) = ((ss)*16 + (bp))
mov ax,[bp+idata] ;含义:(ax) = ((ss)*16 + (bp) + idata)

机器指令处理数据在什么地方

绝大多数机器指令都是进行数据处理的指令,处理大致 可以分为3类:读取、写入、运算,在机器指令这一层来说并不关心数据值的多少,而是关心指令执行前一刻,它将要处理的数据所存放的位置,执行指令之前多要处理的数据可以在三个地方:

  • CPU内部
  • 内存
  • 端口
mov bx,[0]   ;内存,ds:0单元
mov bx,ax    ;CPU内部,ax寄存器
mov bx,1     ;CPU内部,指令缓存器

汇编语言中数据位置的表达

  1. 立即数

对于直接包含在机器指令中的数据(执行前在CPU的指令缓存器中,在汇编语言中称为:立即数(idata)),在汇指令中直接给出。

mov bx,1
add bx,2000h
  1. 寄存器
    指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名字。
mov ax,bx
mov ds,ax
push bx
mov ds:[0],bx
mov ss,ax
  1. 段地址(SA)和偏移地址(EA)
    指令要处理的数据在内存中,在汇编指令中可以使用[X]的格式给出EA,SA在某个段寄存器中;
    存放段地址的寄存器是默认的:
    例如:
mov ax,[0]
mov ax,[di]
mov ax,[bx+8]
mov ax,[bx+si]
mov ax,[bx+si+8]

等指令,段地址默认是ds中;

mov ax,[bp]
mov ax,[bp+8]
mov ax,[bp+8]
mov ax,[bp+si]
mov ax,[bp+si+8]

等指令,段地址默认是在ss中;

寻址方式

当数据存放在内存的时候,我们可以用多种方式来给定这个内存单元的便宜地址,这种定位内存单元的方法一般成为寻址方式。

  1. 通过寄存器指明要处理数据的数据尺寸
mov ax,1
mov al,1

##就是##
2. 在没有寄存器的存在的情况下,使用操作符X ptr 指明内存单元的长度,X在汇编指令中可以为word或byte。
例如:用word ptr指明了指令访问的内存单元是一个字单元

mov word ptr ds:[0],1
inc word ptr [bx]

下面的指令中,用byte ptr指明指令访问的内存单元是一个字节单元:

mov byte ptr ds:[0],1
inc byte ptr ds:[0]
inc byte ptr [bx]
  1. 其它的方法
    有些指令默认了只能访问的是字单元还是字节单元,比如,push [1000H]就不用指明访问的是字单元还是字节单元,因为push指令只能对字进行操作。

讨论一下div指令

div (division);
除数:8位或16位,在寄存器或内存单元中
被除数:(默认)放在AX或DX和AX中
如果是8位,被除数则为16位,默认在AX中存放,如果除数是16位,被除数为32位,在DX和AX中存放,DX中存放高16位,AX中存放低16位。
结果是:如果出事是8位,则AL存储除法操作的商,AH存储除法操作的余数;如果是16位,则AX存储除法操作的商,DX存储除法操作的余数。

除数  被除数
8位   16位(AX)
16位  32位(DX+AX)

为什么除数是8位,被除数是16位但是除数是16位的时候被除数是32位 因为是使用乘法模拟的除法 因此在进行的过程中存在溢出要保证精度必须被除数的位数大于除数的位数这样才能尽量的保证解雇的精度够用
div指令的格式:

div reg
div 内存单元
div byte ptr ds:[0]
含义:(al) = (ax)/((ds)*16 + 0)的商(ah) = (ax)/((ds)*16 + 0)的余数 
div word ptr [bx+si+8]
含义:(ax) = [(dx)*10000H+(ax)]/((ds)*16+(bx)+(si)+8)的商(dx) = [(dx)*10000H+(ax)]/((ds)*16+(bx)+(si)+8)的余数解释:因为当被除数是32位的时候,要在DX中存放高16位在,AX中存放低16位,因此在DX中的实际值是是DX中值的10000H倍,也就相当于向左移16位;

编程实例:

利用除法指令计算 100001/100
移位100001大于65535,因此被除数大于16位要使用32位的被除数,所以只能使用DX和AX两个寄存器联合存放100001,也就是说要进行16位除法,虽然除数100小于255但是由于被除数是32位的因此除数应该放在16位的寄存器中;
100001换成16进制的是186A1H因此程序如下:

mov dx,1
mov ax,86A1H   ;(dx)*10000H+(ax)=100001
mov bx,100
div bx

伪指令dd

dd是用来定义一个dword(double word)双字型数据
例如:

data segmentdb 1   ;字节  bytedw 1   ;字    worddd 1   ;双字  double word

使用div计算data段中的第一个数据除以第二个数据后的结果,商存在第三个数据的存储单元中

数据结构:

data segmentdd 100001dw 100dw 0
data ends

使用div的处理过程:

mov ax,data
mov ds,ax
mov ax,ds:[0]
mov dx,ds:[2]
div word ptr ds:[4]
mov ds:[6],ax

伪指令dup

dup是一个操作符,在汇编语言中同db、dw、dd等一样,也是由汇编器识别处理的符号。它是和db、dw、dd等数据定义的伪指令配合使用,用来进行数据的重复;
例如:

db 3 dup (0)
;定义3个字节,它们的值都是0,相当于 db 0,0,0
db 3 dup (0,1,2)
;定义9个字节,它们的值是0,1,2,0,1,2,0,1,2相当于 db 0,1,2,0,1,2,0,1,2
db 3 dup ('abc','ABC')
;定义18个字节,它们的值是'abcABCabcABCabcABC'相当于 db 'abcABCabcABCabcABC'

可见,dup的使用格式如下:

db 重复的次数 dup (重复的字节型数据)
dw 重复的次数 dup (重复的字型数据)
dd 重复的次数 dup (重复的双字型数据)

dup是一个很有用的操作符,比如定义一个容量为200字节的栈段,如果不用dup则必须使用:

stack segmentdw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends

当然,你可以使用dd,使程序变得简短一些,但是如果定义一个容量为1000字节或10000字节这时候再一个一个定义就显得很吃力了这时使用dup可以轻松的搞定。如下:

stack segment db 200 dup (0)
stack ends

6

汇编中数据处理的基本问题相关推荐

  1. 大脸猫讲逆向之ARM汇编中PC寄存器详解

    i春秋作家:v4ever 近日,在研究一些开源native层hook方案的实现方式,并据此对ARM汇编层中容易出问题的一些地方做了整理,以便后来人能有从中有所收获并应用于现实问题中.当然,文中许多介绍 ...

  2. 区分处理器的字,字长和汇编中的字,双字,四字

    字和字长 64位系统和32位系统中64和32的含义: 64和32指的是CPU中的寄存器(通用)的字长,字长就是一个字的位数.这里说的字的含义是:处理器进行数据处理时,一次存取,加工,和传送的数据长度. ...

  3. 汇编中Enter和Leave指令

    Enter的作用相当==push ebp和mov ebp,esp 这后面两句大家很熟悉吧?函数开始一般都是这两句 Leave的作用相当==mov esp,ebp和pop ebp 而这后面这两句也很常见 ...

  4. 逆向知识十三讲,汇编中数组的表现形式,以及还原数组

    讲解数组之前,要了解数组的特性 1.数据具有连续性 2.数据类型相同 比如: int Ary[3] = {0,1,2}; 我们可以看出,上面定义的数组,数据是连续的,其中每个数据类型大小都是int类型 ...

  5. 汇编中的DW:DW 定义一个字

    汇编中的DW是什么意思?那DB呢 DW 定义一个字 DB 定义一个字节 DD 定义一个双字 前面的D表示定义,后面的字母W .B .D依次表示字(一般为16位).字节(为8位).双字(一般为32位)

  6. ARM汇编:汇编中proc、endp、ret、near、far指令用法

    ARM汇编:汇编中proc.endp.ret.near.far指令用法 子程序名 PROC NEAR ( 或 FAR ) -- ret 子程序名 ENDP (1)NEAR属性(段内近调用): 调用程序 ...

  7. 勿谈大,且看Bloomberg的中数据处理平台

     勿谈大,且看Bloomberg的中数据处理平台 摘要:中数据意味着数据体积已经超越单服务器处理的上限,但也无需使用数千台节点组成的集群--通常是TB级,而不是PB级的.这里,我们不妨走进Bloo ...

  8. Python之pandas:pandas中数据处理常用函数(与空值相关/去重和替代)简介、具体案例、使用方法之详细攻略

    Python之pandas:pandas中数据处理常用函数(与空值相关/去重和替代)简介.具体案例.使用方法之详细攻略 目录 pandas中数据处理常用函数(isnull/dropna/fillna/ ...

  9. 汇编中16进制的写法问题

    在汇编中,16进制的存放不允许字母开头. eg: A8H   这样写是错误的 0A8H  应该这样写 转载于:https://www.cnblogs.com/ciaociao/p/6529132.ht ...

最新文章

  1. 安装 SQL Server 商业解决方案模板
  2. Transact SQL 常用语句以及函数
  3. java基础---System类
  4. 自动登录(过滤器filter的应用)
  5. 测试Live Write的插件
  6. 深度学习(七十)darknet 实现编写mobilenet源码
  7. 【CC2640R2F】香瓜CC2640R2F之LED
  8. FreeSWITCH核心命令
  9. 小滴课堂MySQL相关面试题总结
  10. Android emoji表情处理
  11. 记录一下, 破解某搜题软件
  12. 制作半透明的毛玻璃效果教程
  13. iOS开发 - 使用IJKPlayer时,关于需求要边下边播的缓存功能,退回来后播放缓存不再耗流量
  14. scp ? stall ? scp -t ? scp -f ? MTU
  15. Write 字符输出流
  16. 一起来吐槽:来自暗网的公链项目VAS,竟然内含十级分销?
  17. 股票数据抓取接口文章转载
  18. 关于各种牌子手机的字体问题
  19. linux系统修改屏幕分辨率,Linux系统下更改屏幕分辨率和刷新率方法
  20. 为什么说一站式移动办公SaaS平台一定是未来!

热门文章

  1. 脚本调试工具 Microsoft Script Debugger
  2. 添加新闻在分层里的实现
  3. Golang的指针类型
  4. Windows cmd命令反斜杠问题
  5. 系列博文-Three.js入门指南(张雯莉)-静态demo和three.js功能概览
  6. plsql连接oracle数据库
  7. 项目后台的最新认识和对MVC封装性、可维护性的更深刻认识!
  8. Deepfacelab的填坑之旅
  9. python中调用c库
  10. 详解进程的虚拟内存,物理内存,共享内存