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

news2024/11/26 18:22:33

目录

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 01000010B

I 49H 01001001B
i 69H 01101001B

        接下来,我们学以致用,编写一个将大写字母转换成小写字母, 小写字母转换成大写字母的汇编程序,要求是:第一个字符串:小写字母转换为大写字母;第二个字符串:大写字母转换为小写字母,我们来看看源码。

assume cs:codesg,ds:datasg
datasg segment
	db 'XiaoChenYi '
	db 'I LOVE YOU'
datasg ends

codesg segment
start:
// 遇到小写字母就变大写
	mov ax,datasg
	mov ds,ax
	mov bx,0
	mov cx,10
 s: mov al,[bx]
	and al,11011111b
	mov [bx],al
	inc bx
	loop s
// 遇到大写变小写
	mov bx,11
	mov cx,10
s0: mov al,[bx]
	or al,00100000b
	mov [bx],al
	inc bx
	loop s0

	mov ax,4c00h
	int 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 segment
    db 'ibm             '
    db 'dec             '
    db 'dos             '
    db 'vax             '
datasg ends

        因为有4个字符串,我们可以把它看成一个4行16列的二维数组,我们要修改二维数组的每一行的前3列,所以我们构造一个4x3次的二重循环去解决。

assume cs:codesg,ds:datasg
datasg segment
    db 'ibm             '
    db 'dec             '
    db 'dos             '
    db 'vax             '
datasg ends 

codesg segment 
start:
  mov ax,datasg
  mov ds,ax
  mov bx,0
  mov cx,4
 s0:mov si,0
  mov cx,3
 s:mov al,[bx+si]
  and al,11011111b
  mov [bx+si],al
  inc si
  loop s
  add bx,16
  loop s0

  mov ax,4c00h
  int 21h
codesg ends
end start

        这个代码看起来没什么问题,但是,两次循环都共用了一个寄存器CX,导致循环错误,是得不到正确结果的,那么应该怎么修改呢,我们最后的方法是采用栈去解决。

修改后的代码

assume cs:codesg,ds:datasg,ss:stacksg

datasg segment
    db 'ibm             '
    db 'dec             '
    db 'dos             '
    db 'vax             '
datasg ends 

stacksg segment
    dw 0,0,0,0,0,0,0,0    ;定义的栈
stacksg ends

codesg segment
start:mov ax,stacksg
    mov ss,ax
    mov sp,16
    mov ax,datasg
    mov ds,ax
    mov bx,0

    mov cx,4

 s0:push cx      ; 外层循环cx值压栈
    mov si,0
    mov cx,3      ; cx设置为内层循环的次数

 s:mov al,[bx+si]
   and al,11011111b
   mov [bx+si],al
   inc si
   loop s

   add bx,16
   pop cx      ; 外层循环cx值出栈
   loop s0      ; 外层循环

   mov ax,4c00h
   int 21h
codesg ends
end start

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/143432.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

进程间通信——信号

目录 1 概念 2 信号类型 linux的基本信号类型 操作 常用的信号 3 怎么操作信号 signal kill raise alarm pause 注意 范例1(自己用信号发送书写sleep函数实现定时炸弹) 范例2(用信号发送书写功能检测用户是否输入,如…

OAuth2.0协议流程与授权模式、协议流程

什么是OAuth2.0OAuth(Open Authorization)是一个关于授权(authorization)的开放网络标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分…

Java 如何优雅的导出 Excel

前言 公司项目最近有一个需要:报表导出。整个系统下来,起码超过一百张报表需要导出。这个时候如何优雅的实现报表导出,释放生产力就显得很重要了。下面主要给大家分享一下该工具类的使用方法与实现思路。 实现的功能点 对于每个报表都相同…

看零信任如何基于PKI体系实现数字信任

谈到安全,在万物互联的数字世界里,生活和工作之间的界限正在变得越来越模糊,传统的边界不再适用,传统的安全手段也不再适用。数字转型的步伐虽在不断加速,但威胁载体也在不断发展壮大,在数字互动过程中&…

从0到1完成一个Vue后台管理项目(三、使用SCSS/LESS,安装图标库)

往期 从0到1完成一个Vue后台管理项目(一、创建项目) 从0到1完成一个Vue后台管理项目(二、使用element-ui) 安装CSS预处理器 Sass cnpm i sass-loader7 node-sass4 -S 安装完就可以使用了,通过lang的方式 这里注意自…

C#,桌面编程入门(01)——按钮Button属性与事件、动态创建、快捷键、控件数组及自定义Button

本文是《桌面编程入门》系列文章的开山之篇。《桌面编程入门》系列文章主要介绍桌面编程的各种组件,Button,ComboBox,Panel,WebBrowser。。。。。。类似的文章非常多,深度不同,水平不等。1 桌面编程1.1 图形…

第六天作业部分

使用的文件内容 1:passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shut…

0. 【R、Rstudio、Rtools 】软件的安装 + 在Rstudio上永久修改(默认工作路径 + 默认安装包路径)

文章目录1.R软件安装2. Rstudio的安装3. Rtools 的安装4. 初始化Rstudio4.1 更改Rtudio的镜像为中国清华大学,下载包更快4.2. 修改默认工作路径 默认安装包路径全部都在官网下,都是免费的 1.R软件安装 访问官网:https://www.r-project.org/ …

React(coderwhy)- 04(css)

React中CSS的概述 组件化天下的CSS ◼ 前面说过,整个前端已经是组件化的天下:  而CSS的设计就不是为组件化而生的,所以在目前组件化的框架中都在需要一种合适的CSS解决方案。 ◼ 在组件化中选择合适的CSS解决方案应该符合以下条件&#xff…

为外贸软件花钱前,需要考虑的几大因素

当外贸企业发展壮大到一定程度时,购买一款适合公司、产品、业务的办公软件帮助员工更好的处理工作是必然的选择。如何挑选一款真正便捷高效的软件产品,特别是在花费几万甚至十几万购买外贸软件之前,一定要谨慎考虑以下几个问题。 一、使用便捷…

如何选择合适的文档管理解决方案?

如何选择合适的文档管理解决方案? 合适的文档管理解决方案有助于保护您的数据、数字化纸质流程、保持业务连续性、满足合规性标准并为审计做好准备。 但并非所有文档管理解决方案都相同 —— 要真正实现这些好处,您需要一个满足某些条件的系统。 文档管…

【Linux修炼】12.深入了解系统文件

每一个不曾起舞的日子,都是对生命的辜负。 文件fd一. 重新谈论文件1. 共识的问题2. 重谈C语言文件操作2.1 概要2.2 C语言文件实操2.3 OS接口open的使用(比特位标记)2.4 写入操作2.5 追加操作2.6 只读操作二. 如何理解文件1. 提出问题2. 文件描…

Java 空指针异常的若干解决方案

Java 中任何对象都有可能为空,当我们调用空对象的方法时就会抛出 NullPointerException 空指针异常,这是一种非常常见的错误类型。我们可以使用若干种方法来避免产生这类异常,使得我们的代码更为健壮。本文将列举这些解决方案,包括…

实验十六 BGP协议基本配置

实验十六 BGP协议基本配置边界网关协议BGP(Border Gateway Protocol)是一种实现自治系统AS(Autonomous System) 之间的路由可达,并选择最佳路由的距离矢量路由协议。 自治系统AS (Autonomous System) AS是指在一个实体管辖下的拥有相同选路策略的IP网络。BGP网络中的…

Vue3 实现验证码倒计时

前言 倒计时的运用场景&#xff1a;获取手机验证码倒计时、获取邮箱验证码倒计时等场景&#xff0c;废话不多说&#xff0c;开始吧。 实现效果 实现代码 html&#xff08;重要部分&#xff09; <template><el-button v-if"!sms.disabled" color"#f…

通达信l2接口如何用?

在股票量化投资领域中&#xff0c;通达信l2接口如何用的知识也是要知道和了解的&#xff0c;像现在特别多的团队已经开发有多种不一样的数据接口系统&#xff0c;主要是方便大家去查询行情的时候&#xff0c;能够很快的从这些l2数据接口中产生数据&#xff0c;直观的显示数据的…

酷早报:2023年1月6日全球Web3加密行业重大资讯大汇总

2023年1月6日 星期五 【数据指标】 加密货币总市值&#xff1a;$0.82万亿 BTC市值占比&#xff1a;39.42% 恐慌贪婪指数&#xff1a;26 恐慌【今日快讯】 1、【政讯】 1.1.1、国际货币基金组织IMF&#xff1a;美国通胀尚未“转危为安” 美联储需加息到底 1.1.2、美联储布拉德&a…

Servlet是什么?有哪些优点?

Servlet是使用Java语言编写的运行在服务器端的程序。狭义的Servlet是指Java语言实现的一个接口&#xff0c;广义的Servlet是指任何实现了这个Servlet接口的类&#xff0c;一般情况下&#xff0c;人们将Servlet理解为后者。Servlet主要用于处理客户端传来的HTTP请求&#xff0c;…

【数组经典题目】总结篇

【数组经典题目】总结篇1 二分法2 双指针法3 滑动窗口4 模拟行为5 总结1 二分法 【数组】leetcode704.二分查找(C/C/Java/Js) 使用暴力解法&#xff0c;通过这道题目&#xff0c;如果追求更优的算法&#xff0c;建议试一试用二分法&#xff0c;来解决这道题目 暴力解法时间复…

机器学习实战教程(十):提升分类器性能利器-AdaBoost

一、前言前面的文章已经介绍了五种不同的分类器&#xff0c;它们各有优缺点。我们可以很自然地将不同的分类器组合起来&#xff0c;而这种组合结果则被成为集成方法(ensemble method)或者元算法(meta-algorithm)。使用集成方法时会有多种形式&#xff1a;可以是不同算法的集成&…