(七)汇编语言——更灵活的定位内存地址的方法
目录
and和or
ASCII码
[bx+idata]
SI和DI寄存器
[bx+si]和[bx+di]
[bx+si+idata]和[bx+di+idata]
总结
例子(双重循环的解决方案)
我们知道,对于汇编来说,内存是极为重要的,所以,能精准且巧妙地定位内存地址是非常重要的。接下来,我们就来简单介绍一下定位内存地址的几种方法吧!但是在这之前,我们还要学习一些其他的知识点,就让我们开始今天的学习吧!
and和or
这个比较简单,就是按位与(and)和按位或(or),具体用法如下所示:
// 这个就是将第6位置为0,其他不变
and al,11011111b
// 这个就是将第6位置为1,其他不变
or al,00100000b
ASCII码
这个比较简单,相信大家都清楚这个,但是我需要补充一点点,就是关于大小写字母的联系,大家可以看到,大小写之间就是第6位不同,其他都是相同的,这也为我们进行大小写转化提供了思路,只需要用与或命令即可。
// 大家可以看到,大小写之间就是第6位不同,其他都是相同的
b 62H 01100010B
B 42H 01000010BI 49H 01001001B
i 69H 01101001B
接下来,我们学以致用,编写一个将大写字母转换成小写字母, 小写字母转换成大写字母的汇编程序,要求是:第一个字符串:小写字母转换为大写字母;第二个字符串:大写字母转换为小写字母,我们来看看源码。
assume cs:codesg,ds:datasg
datasg segmentdb 'XiaoChenYi 'db 'I LOVE YOU'
datasg endscodesg segment
start:
// 遇到小写字母就变大写mov ax,datasgmov ds,axmov bx,0mov cx,10s: mov al,[bx]and al,11011111bmov [bx],alinc bxloop s
// 遇到大写变小写mov bx,11mov cx,10
s0: mov al,[bx]or al,00100000bmov [bx],alinc bxloop s0mov ax,4c00hint 21h
codesg ends
end start
我们可以看到,代码的运行是正确的,当然了,数据中包含了空格,不是字母,但是运行也是没有问题的哈!
[bx+idata]
接下来我们就来讲一些难度稍微大一点的东西了,开始介绍各种寻址方式了,这部分较为硬核,而且比较多,接下来我们就开始介绍噢!
[bx+idata]表示一个内存单元,它的偏移地址为(bx)+idata(bx中的数值加上idata,idata是常数,之前介绍过,就不再介绍了)。我们举个例子来详细介绍一下:
mov ax,[bx+200]
就这一个指令,就代表着内存单元的段地址在ds中,偏移地址为200加上bx中的数值,数学化的描述为:(ax)=((ds)*16+200+(bx))。他还有有一些其他的写法,我们举个例子看看:
mov ax,200[bx]
比如这个例子,看起来有点像C语言里面的数组,好的,那我们就这样去理解它,其中200,代表(ds)*16+200,是一个固定的地址,相当于数组的起始地址,然后[bx],代表着偏移地址,这么看起来,这个和C语言的数组还是很像的,准确的来说,C语言就是按照这个来设计的,哈哈哈,毕竟汇编是比C还要古老的语言。所以一些能用数组解的题目,我们都能用这种寻址方式去解了。
SI和DI寄存器
SI、DI这两个寄存器我们管他叫变址寄存器,主要的功能和bx类似,但是SI和DI不能够分成两个8位寄存器来使用,这就是他们之间的区别。具体的用法我们就不在这里详细讲解,看我们后面的例子就能够理解其主要的用法。
- mov bx,0
- mov ax,[bx]
- mov si,0
- mov ax,[si]
- mov di,0
- mov ax,[di]
我们只需要知道,这三种写法的效果是相同的就行,因为这三个寄存器的作用是相似的。
[bx+si]和[bx+di]
[bx+si]表示一个内存单元的偏移地址为(bx)+(si)(即bx中的数值加上si中的数值)。数学表达式为(ax)=((ds)*16+(bx)+(si))。他有一个其他的写法:
mov ax,[bx][si]
这样看起来是不是很像二维数组呢,猜对了。这个给人的感觉就像是二维数组,bx表示一个偏移地址,si表示另外一个偏移地址,这就像是我们的二维数组,哈哈哈。
[bx+si+idata]和[bx+di+idata]
接下来我们组合一下上面的两种寻址方式,于是我们得到了上面这两种寻址方式:[bx+si+idata]和[bx+di+idata],表示一个内存单元偏移地址为(bx)+(si)+idata,即bx中的数值加上si中的数值再加上idata,数学化的描述:(ax)=((ds)*16+(bx)+(si)+idata)。他还有一个其他的写法:
mov ax,[bx].idata[si]
这个大家看一下,是不是感觉很像C语言里面的结构体,没错,这就类似于结构体,这个的话就是用bx定位整个结构体,用idata定位结构体中的某一个数据项,用si定位数据项中的元素。我们可以看到,下面几个是等价的。
// c语言
person.name[i] = 'Y';// 汇编
mov byte ptr [bx].idata[si],'Y'
这里面出现了 byte ptr ,接下来我们就来看一下这个是什么意思,其实这个主要是用来告诉CPU,我们需要处理的数据有多长,在没有寄存器参与的内存单元访问指令中,用word ptr(字)或byte ptr(字节)显性地指明所要访问的内存单元的长度是很必要的,否则,CPU无法得知所要访问的单元是字单元,还是字节单元。
总结
形式 | 名称 | 特点 | 特点 | 示例 |
[idata] | 直接寻址 | 用一个常量/立即数来表示地址 | 用于直接定位一个内存单元 | mov ax,[200] |
[bx] | 寄存器间接寻址 | 用一个变量来表示内存地址 | 用于间接定位一个内存单元 |
mov bx,0 mov ax,[bx] |
[bx+idata] | 寄存器相对寻址 | 用一个变量和常量表示地址 | 可在一个起始地址的基础上用变量间接定位一个内存单元 |
mov bx,4 mov ax,[bx+200] |
[bx+si] | 基址变址寻址 | 用两个变量表示地址 | mov ax,[bx+si] | |
[bx+si+idata] | 相对基址变址寻址 | 用两个变量和一个常量表示地址 | mov ax,[bx+si+200] |
例子(双重循环的解决方案)
首先,我们来看一下一个例子:编程将datasg段中每个单词改为大写字母。
datasg segmentdb 'ibm 'db 'dec 'db 'dos 'db 'vax '
datasg ends
因为有4个字符串,我们可以把它看成一个4行16列的二维数组,我们要修改二维数组的每一行的前3列,所以我们构造一个4x3次的二重循环去解决。
assume cs:codesg,ds:datasg
datasg segmentdb 'ibm 'db 'dec 'db 'dos 'db 'vax '
datasg ends codesg segment
start:mov ax,datasgmov ds,axmov bx,0mov cx,4s0:mov si,0mov cx,3s:mov al,[bx+si]and al,11011111bmov [bx+si],alinc siloop sadd bx,16loop s0mov ax,4c00hint 21h
codesg ends
end start
这个代码看起来没什么问题,但是,两次循环都共用了一个寄存器CX,导致循环错误,是得不到正确结果的,那么应该怎么修改呢,我们最后的方法是采用栈去解决。
修改后的代码
assume cs:codesg,ds:datasg,ss:stacksgdatasg segmentdb 'ibm 'db 'dec 'db 'dos 'db 'vax '
datasg ends stacksg segmentdw 0,0,0,0,0,0,0,0 ;定义的栈
stacksg endscodesg segment
start:mov ax,stacksgmov ss,axmov sp,16mov ax,datasgmov ds,axmov bx,0mov cx,4s0:push cx ; 外层循环cx值压栈mov si,0mov cx,3 ; cx设置为内层循环的次数s:mov al,[bx+si]and al,11011111bmov [bx+si],alinc siloop sadd bx,16pop cx ; 外层循环cx值出栈loop s0 ; 外层循环mov ax,4c00hint 21h
codesg ends
end start
这样就可以完美解决双重循环的问题了!
好啦,关于寻址,我们就先讲解这么多,继续加油哦!还有一点,就是千万不能使用中文空格!!!千万不能使用中文空格!!!千万不能使用中文空格!!!
(七)汇编语言——更灵活的定位内存地址的方法相关推荐
- [汇编语言]更灵活的定位内存地址的方法
目录 一.and和or指令 二.以字符的形式给出数据 三.大小写转化问题 四.[bx+idata] 五.SI和DI 六.[bx+si]和[bx+di] 与 [bx+si+idata]和[bx+di+i ...
- 汇编语言-更灵活的定位内存地址的方法
目录 一.and和or指令 1.补充知识: 2.and指令 3.or指令 二.以字符的形式给出的数据 三.大小写转换 ACSII码值对照表: 一.and和or指令 1.补充知识: 与运算(&) ...
- 更灵活的定位内存地址的方法02 - 零基础入门学习汇编语言33
第七章:更灵活的定位内存地址的方法02 让编程改变世界 Change the world by program [bx+idata] 在前面,我们可以用[bx]的方式来指明一个内存单元, 我们还可以用 ...
- 更灵活的定位内存地址的方法05 - 零基础入门学习汇编语言36
第七章:更灵活的定位内存地址的方法05 让编程改变世界 Change the world by program 问题7.8 [codesyntax lang="asm"] assu ...
- 更灵活的定位内存地址的方法---汇编学习笔记
更灵活的定位内存地址的方法 前面,我们用[0].[bx]的方法,在访问内存的指令中,定位内存单元的地址.本章将用更灵活的方式来定位内存地址. 7.1 and和or指令 (1)and指令:逻辑与指令,按 ...
- 汇编: 更灵活的定位内存地址的方法
bx是偏移地址寄存器.同样的, si,di也是偏移地址寄存器. 这样使用了si,di可以更灵活的定位内存地址. assume cs:codecode segmentstart: mov bx,0mov ...
- 王爽 汇编语言第三版 第7章 --- 更灵活的定位内存地址的方法(可以理解为 数组形式的内存定位)
汇编语言(第三版)王爽著 的十二个实验:https://blog.csdn.net/OrangeHap/article/details/89791064 大小端 字节对齐 对于 arm,intel 这 ...
- 《汇编语言》总结04 —— 更灵活的定位内存地址的方法
(一)and和or指令 and指令:逻辑与指令,按位进行与运算 mov al,01100011B and al,00111011B 执行后,al=00100011B 作用:通过该指令可将操作对象的相应 ...
- 汇编语言-王爽 第7章 更灵活的定位内存地址的方法-笔记
将datasg中的第一个字符串转化为大写,第二个字符串转化为小写. 第一种方法: assume cs:codesg,ds:datasgdatasg segmentdb 'BaSic'db 'iNfOr ...
最新文章
- poj3468 A Simple Problem with Integers
- The Class Loader Hierarchy--转载
- 【PAT乙级】1040 有几个PAT (25 分)
- 动态代理的两种方式_动态代理是基于什么原理?
- poj 1218(经典开关问题,模拟)
- 打开端口_打印机ip及端口设置
- python模块import具体用法
- 分页及页码导航 用户控件
- python获取类的类属性_Python中如何获取类属性的列表
- 云计算机的优点,介绍云的优点和注意事项
- ES6-ES11新特性_ECMAScript相关名词介绍_---JavaScript_ECMAScript工作笔记002
- PHP面试题:HTTP中POST、GET、PUT、DELETE方式的区别
- y480 linux无线网卡驱动,联想y480无线网卡驱动下载-联想y480笔记本网卡驱动v15.0.0.75 官方版 - 极光下载站...
- 【数字电路逻辑设计】第1章 基本知识
- 徐培成大数据第一季java基础-徐培成-专题视频课程
- php格式化 货币,php – 使用numberFormatter格式化货币
- 计算机连接路由器的方法,路由器连接电脑的三种方式和设置介绍
- 安卓模拟器绕过模拟器检测正常用电脑玩手机游戏的最好解决方法
- 在MATLAB中创建函数
- [11]Debugging in Studio-UiPath ARD Certification Training
热门文章
- 读《从0开始学大数据》-- 学习笔记和感想随笔(一)
- java字符转数字_Java字符串和数字间的转换
- 大锅乱炖10大 H5 前端框架
- 【最新版】多功能萝卜抽奖系统小程序源码
- 导出GoodNotes录音
- 微服务分布式事务解决方案Seata
- jquery从零开始-2.2 结构选择器(一)
- 路边烟酒店明明没什么客人,为什么一年还能赚几十万?原因很简单
- 浙江去年拘留“老赖”3.3万人次 失信黑名单扩容29万条
- keil c语言中位取反,关于按位取反“~”的故事