目录

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位寄存器来使用,这就是他们之间的区别。具体的用法我们就不在这里详细讲解,看我们后面的例子就能够理解其主要的用法。

  1. mov bx,0
  2. mov ax,[bx]
  3. mov si,0
  4. mov ax,[si]
  5. mov di,0
  6. 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

这样就可以完美解决双重循环的问题了!

好啦,关于寻址,我们就先讲解这么多,继续加油哦!还有一点,就是千万不能使用中文空格!!!千万不能使用中文空格!!!千万不能使用中文空格!!!

(七)汇编语言——更灵活的定位内存地址的方法相关推荐

  1. [汇编语言]更灵活的定位内存地址的方法

    目录 一.and和or指令 二.以字符的形式给出数据 三.大小写转化问题 四.[bx+idata] 五.SI和DI 六.[bx+si]和[bx+di] 与 [bx+si+idata]和[bx+di+i ...

  2. 汇编语言-更灵活的定位内存地址的方法

    目录 一.and和or指令 1.补充知识: 2.and指令 3.or指令 二.以字符的形式给出的数据 三.大小写转换 ACSII码值对照表: 一.and和or指令 1.补充知识: 与运算(&) ...

  3. 更灵活的定位内存地址的方法02 - 零基础入门学习汇编语言33

    第七章:更灵活的定位内存地址的方法02 让编程改变世界 Change the world by program [bx+idata] 在前面,我们可以用[bx]的方式来指明一个内存单元, 我们还可以用 ...

  4. 更灵活的定位内存地址的方法05 - 零基础入门学习汇编语言36

    第七章:更灵活的定位内存地址的方法05 让编程改变世界 Change the world by program 问题7.8 [codesyntax lang="asm"] assu ...

  5. 更灵活的定位内存地址的方法---汇编学习笔记

    更灵活的定位内存地址的方法 前面,我们用[0].[bx]的方法,在访问内存的指令中,定位内存单元的地址.本章将用更灵活的方式来定位内存地址. 7.1 and和or指令 (1)and指令:逻辑与指令,按 ...

  6. 汇编: 更灵活的定位内存地址的方法

    bx是偏移地址寄存器.同样的, si,di也是偏移地址寄存器. 这样使用了si,di可以更灵活的定位内存地址. assume cs:codecode segmentstart: mov bx,0mov ...

  7. 王爽 汇编语言第三版 第7章 --- 更灵活的定位内存地址的方法(可以理解为 数组形式的内存定位)

    汇编语言(第三版)王爽著 的十二个实验:https://blog.csdn.net/OrangeHap/article/details/89791064 大小端 字节对齐 对于 arm,intel 这 ...

  8. 《汇编语言》总结04 —— 更灵活的定位内存地址的方法

    (一)and和or指令 and指令:逻辑与指令,按位进行与运算 mov al,01100011B and al,00111011B 执行后,al=00100011B 作用:通过该指令可将操作对象的相应 ...

  9. 汇编语言-王爽 第7章 更灵活的定位内存地址的方法-笔记

    将datasg中的第一个字符串转化为大写,第二个字符串转化为小写. 第一种方法: assume cs:codesg,ds:datasgdatasg segmentdb 'BaSic'db 'iNfOr ...

最新文章

  1. poj3468 A Simple Problem with Integers
  2. The Class Loader Hierarchy--转载
  3. 【PAT乙级】1040 有几个PAT (25 分)
  4. 动态代理的两种方式_动态代理是基于什么原理?
  5. poj 1218(经典开关问题,模拟)
  6. 打开端口_打印机ip及端口设置
  7. python模块import具体用法
  8. 分页及页码导航 用户控件
  9. python获取类的类属性_Python中如何获取类属性的列表
  10. 云计算机的优点,介绍云的优点和注意事项
  11. ES6-ES11新特性_ECMAScript相关名词介绍_---JavaScript_ECMAScript工作笔记002
  12. PHP面试题:HTTP中POST、GET、PUT、DELETE方式的区别
  13. y480 linux无线网卡驱动,联想y480无线网卡驱动下载-联想y480笔记本网卡驱动v15.0.0.75 官方版 - 极光下载站...
  14. 【数字电路逻辑设计】第1章 基本知识
  15. 徐培成大数据第一季java基础-徐培成-专题视频课程
  16. php格式化 货币,php – 使用numberFormatter格式化货币
  17. 计算机连接路由器的方法,路由器连接电脑的三种方式和设置介绍
  18. 安卓模拟器绕过模拟器检测正常用电脑玩手机游戏的最好解决方法
  19. 在MATLAB中创建函数
  20. [11]Debugging in Studio-UiPath ARD Certification Training

热门文章

  1. 读《从0开始学大数据》-- 学习笔记和感想随笔(一)
  2. java字符转数字_Java字符串和数字间的转换
  3. 大锅乱炖10大 H5 前端框架
  4. 【最新版】多功能萝卜抽奖系统小程序源码
  5. 导出GoodNotes录音
  6. 微服务分布式事务解决方案Seata
  7. jquery从零开始-2.2 结构选择器(一)
  8. 路边烟酒店明明没什么客人,为什么一年还能赚几十万?原因很简单
  9. 浙江去年拘留“老赖”3.3万人次 失信黑名单扩容29万条
  10. keil c语言中位取反,关于按位取反“~”的故事