更灵活的定位内存地址的方法

文章目录

  • 更灵活的定位内存地址的方法
    • and和or指令
    • 关于ASCII码
    • 以字符形式给出的数据
    • 大小写转换的问题
    • [bx+idata]
    • 用[bx+idata]的方式进行数组的处理
    • SI和DI
    • [bx+si]和[bx+di]
    • [bx+si+idata]和[bx+di+idata]
    • 不同的寻址方式的灵活应用
      • 题目示例

更灵活的定位内存地址的方法

and和or指令

1)and 指令:逻辑指令,按位进行与运算。

​ 如 mov al, 01100011B

​ and al, 00111011B

​ 执行后:al = 00100011B

通过该指令可将操作对象的相应位设为0,其他位不变。

2)or 指令:逻辑指令,按位进行或运算。

​ 如 mov al, 01100011B

​ and al, 00111011B

​ 执行后:al = 01111011B

通过该指令可将操作对象的相应位设为1,其他位不变。

关于ASCII码

世界上有很多编码方案,有种方案叫做ASCII编码,是在计算机系统中通常被采用的。

简单地说,所谓编码方案,就是一套规则,它约定了用什么样的信息来表示现实对象。

比如说,在ASCII编码方案中,用 61H 表示“a”,62H表示“b”。

以字符形式给出的数据

我们可以在汇编程序中,用 '…'的方式指明数据是以字符的形式给出的,编译器将把它们转化为相对应的ASCII码。

assume ds:data
data segmentdb 'unIX' db 'foRK'
data endscode segmentstart: mov al,'a'mov bl,'b'mov ax,4c00hint 21h
code ends  
end start                

上面的源程序中:

“db ‘unIX’ ” 相当于“db 75H,6EH,49H,58H”, “u”、 “n”、 “I”、 “X”的ASCII码分别为75H、6EH、49H、58H;

“db ‘foRK’ ” 相当于“db 66H,6FH,52H,4BH”, “u”、 “n”、 “I”、 “X”的ASCII码分别为66H、6FH、52H、4BH;

“mov al,’a’”相当于“mov al,61H”,”a”的ASCII码为61H;

“mov al,’b’”相当于“mov al,62H”,”b”的ASCII码为62H。

大小写转换的问题

我们知道同一个字母的大写字符和小写字符对应的 ASCII 码是不同的,比如 “A” 的 ASCII 码是41H,“a”的ASCII码是61H。

要改变一个字母的大小写,实际上就是要改变它所对应的ASCII 码。

我们可以看出来,小写字母的ASCII码值比大写字母的ASCII码值大20H 。

一个字母,不管它原来是大写还是小写,将它的第5位置0,它就必将变为大写字母;将它的第5位置1,它就必将变为小写字母。

代码如下:

assume cs: codesg, ds: datasgdatasg segmentdb 'BaSic"db 'iNfOrMaTiOn'
datasg endscodesg segmentstart:  mov ax,datasgmov ds,ax		;设置ds指向datasg段mov bx,0		;设置(bx)=0,ds:bx指向'BaSiC’的第一个字母mov cx,5		;设置循环次数5,因为'BaSic1有5个字母s:	mov al,[bx]		;将ASCII码从ds:bx所指向的单元中取出and al,11011111B	;将al中的ASCII码的第5位置为0,变为大写字母mov [bx],al		;将转变后的ASCII码写回原单元inc bx			;(bx)加1,ds:bx指向下一个字母loop smov bx,5		;设置(bx)=5,ds:bx指向'iNfOrMaTiOn'的第一个字母mov cx,11		;设置循环次数11,因为'iNfOrMaTiOn'有11个字母s0:	mov al,[bx]or al,00100000B	;将al中的ASCII码的第5位置为1,变为小写字母mov [bx],alinc bxloop somov ax,4c00hint 21h
codesg ends
end start

[bx+idata]

我们可以用一种更为灵活的方式来指明内存单元: [bx+idata]表示一个内存单元,它的偏移地址为(bx)+idata(bx中的数值加上idata)。

用[bx+idata]的方式进行数组的处理

在codesg中填写代码,将datasg中定义的第一个字符串,转化为大写,第二个字符串转化为小写。

assume cs:codesg,ds:datasg
datasg segment
db 'BaSiC'
db 'MinIX'
datasg endscodesg segmentstart: ……
codesg ends
end start

我们观察datasg段中的两个字符串,一个的起始地址为0,另一个的起始地址为5。

我们可以将这两个字符串看作两个数组,一个从0地址开始存放,另一个从5开始存放。

我们观察datasg段中的两个字符串,一个的起始地址为0,另一个的起始地址为5。

我们可以将这两个字符串看作两个数组,一个从0地址开始存放,另一个从5开始存放。

    mov ax,datasgmov ds,axmov bx,0mov cx,5
s:	mov al,[bx]		;定位第一个字符串的字符and al,11011111bmov [bx],almov al,[5+bx]	;定位第二个字符串的字符or al,00100000bmov [5+bx],alinc bxloop s

SI和DI

SI和DI是8086CPU中和bx功能相近的寄存器,但是SI和DI不能够分成两个8 位寄存器来使用。

用寄存器SI和DI实现将字符串‘welcome to masm!’复制到它后面的数据区中。

assume cs:codesg,ds:datasg
datasg segment db 'welcome to masm!'db '................'
datasg ends

因为 “welcome to masm!”从偏移地址0开始存放,长度为 16 个字节,所以,它后面的数据区的偏移地址为 16 ,就是字符串所要存放的空间。

我们用ds:si 指向要复制的源始字符串,用 ds:di 指向复制的目的空间,然后用一个循环来完成复制。

代码如下:

codesg segment
start: mov ax,datasgmov ds,axmov si,0mov di,16mov cx,8s:   mov ax,[si]mov [di],axadd si,2add di,2loop smov ax,4c00hint 21h
codesg ends
end start

[bx+si]和[bx+di]

[bx+si]表示一个内存单元,它的偏移地址为(bx)+(si)(即bx中的数值加上si中的数值)。([bx+di]同理)

mov ax,[bx+si]的含义:

将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为bx中的数值加上si中的数值,段地址在ds中。

[bx+si+idata]和[bx+di+idata]

[bx+si+idata]表示一个内存单元,它的偏移地址为(bx)+(si)+idata。(即bx中的数值加上si中的数值再加上idata)

指令mov ax,[bx+si+idata]的含义:

将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为bx中的数值加上si中的数值再加上idata,段地址在ds中。

该指令也可以写成如下格式(常用):

  • mov ax,[bx+200+si]
  • mov ax,[200+bx+si]
  • mov ax,200[bx][si]
  • mov ax,[bx].200[si]
  • mov ax,[bx][si].200

不同的寻址方式的灵活应用

如果我们比较一下前面用到的几种定位内存地址的方法(可称为寻址方式),就可以发现有以下几种方式:

1)[idata] 用一个常量来表示地址,可用于直接定位一个内存单元;

2)[bx] 用一个变量来表示内存地址,可用于间接定位一个内存单元;

3)[bx+idata] 用一个变量和常量表示地址,可在一个起始地址的基础上用变量间接定位一个内存单元;

4)[bx+si] 用两个变量表示地址;

5)[bx+si+idata] 用两个变量和一个常量表示地址。

题目示例

1)编程,将datasg段中每个单词的头一个字母改为大写字母。

assume cs:codesg,ds:datasg
datasg segmentdb '1. file          'db '2. edit         'db '3. search     'db '4. view        'db '5. options    'db '6. help        '
datasg endscodesg segmentstart:……
codesg ends
end start

datasg中的数据的存储结构,如图:

请添加图片描述

我们可以看到:在datasg中定义了6个字符串,每个长度为16字节。(注意,为了直观,每个字符串的后面都加上了空格符,以使它们的长度刚好为16字节)

我们用bx作变量,定位每行的起始地址,用3定位要修改的列,用[bx+idata]的方式来对目标单元进行寻址。

程序如下:

mov ax,datasg
mov ds,ax
mov bx,0
mov cx,6
s:	mov al,[bx+3]and al,11011111b mov [bx+3],al add bx,16
loop s

2)编程:将datasg段中每个单词改为大写字母。

assume cs:codesg,ds:datasg
datasg segmentdb 'ibm            'db 'dec            'db 'dos            'db 'vax            '
datasg endscodesg segmentstart: ……
codesg ends
end start

在datasg中定义了4个字符串,每个长度为16字节。(注意,为了使我们在Debug 中可以直观地查看,每个字符串的后面都加上了空格符,以使它们的长度刚好为16byte)

因为它们是连续存放的,我们可以将这 4 个字符串看成一个 4行16列的二维数组。

按照要求,我们需要修改每一个单词,即二维数组的每一行的前3列。

我们用bx来作变量,定位每行的起始地址,用si 定位要修改的列,用 [bx+si] 的方式来对目标单元进行寻址。

我们需要用到二重循环,应该在每次开始内层循环的时候,将外层循环的cx中的数值保存起来,在执行外层循环的loop指令前,再恢复外层循环的cx数值。

我们可以用dx来暂时存放cx中的值,但在程序较为复杂的情况下dx有可能已被占用。

因此在需要暂存数据的时候,我们都应该使用栈,栈空间在内存中,采用相关的指令,如:push、pop等,可对其进行特殊的操作。

程序如下:

assume cs:codesg,ds:datasg,ss:stacksg
datasg segmentdb 'ibm            ' db 'dec            ' db 'dos            ' db 'vax            ' 
datasg endsstacksg segmentdw 0,0,0,0,0,0,0,0		;定义一个段,用来做栈段,容量为16个字节
stacksg endscodesg segmentstart:  mov ax,stacksgmov ss,axmov sp,16mov ax,datasgmov ds,axmov bx,0mov cx,4s0:     push cx 		;将外层的cx值压栈mov si,0 mov cx,3		;设置内层循环的次数s:      mov al,[bx+si]and al,11011111b mov [bx+si],al inc siloop sadd bx,16 pop cx 			;从栈顶弹出源cx的值,恢复cxloop sO			;外层循环的loop指令将cx中的计数值-1mov ax,4c00Hint 21Hcodesg ends
end start

3)编程,将datasg段中每个单词的前四个字母改为大写字母。

assume cs:codesg,ds:datasg,ss:stacksg
stacksg segmentdw 0,0,0,0,0,0,0,0
stacksg ends
datasg segmentdb '1. display......'db '2. brows........'db '3. replace......'db '4. modify.......'
datasg ends
codesg segment
start: ……
codesg ends
end start

由于数据是连续存放的,我们可以将这4个字符串看成一个4行16列的二维数组,按照要求,我们需要修改每个单词的前四个字母,即二维数组的每一行的3~6列。

我们需要进行4x4次的二重循环,用变量R定位行,常量3定位每行要修改的起始列,变量C定位相对于起始列的要修改的列。

程序如下:

assume cs:codesg,ds:datasg,ss:stacksgstacksg segmentdw 0,0,0,0,0,0,0,0
stacksg endsdatasg segmentdb '1. display......'db '2. brows........'db '3. replace......'db '4. modify.......'
datasg endscodesg segmentstart:  mov ax,stacksgmov ss,axmov sp,16mov ax,datasgmov ds,axmov bx,0mov cx,4s0:		push cxmov si,4mov cx,4s:		mov al,[bx+si]add al,11011111binc siloop spop cxadd bx,16loop s0mov ax,4c00Hint 21Hcodesg ends
end start

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

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

相关文章

Axure RP 8中文---快速原型设计工具,一站式解决方案

Axure RP 8是一款专业的快速原型设计工具,以其直观易用的界面和丰富的功能受到广大用户的青睐。它支持用户通过拖放操作快速创建交互式原型,包括线框图、流程图等,并具备高保真度的设计能力。Axure RP 8还提供了团队协作和共享功能&#xff0…

【Java程序设计】【C00368】基于(JavaWeb)Springboot的箱包存储系统(有论文)

TOC 博主介绍:java高级开发,从事互联网行业六年,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,博客中有上百套程序可供参考,欢迎共同交流学习。 项目简介 项目获取 🍅文末点击卡片…

基于nodejs+vue铁路订票管理系统python-flask-django-php

该铁路订票管理系统采用前后端分离进行设计,并采用nodejs语言以及express框架进行开发。本系统主要设计并完成了用户登录管理过程、个人信息修改、用户管理、火车类型管理、火车信息管理、车票预订管理、车票退票管理、系统管理等功能。该系统操作简单,界…

13_Linux内核配置选项

内核配置选项 内核配置通常是对内核支持的各个功能进行取舍配置,将配置的方案保存到 configure文件中。在编译内核的时候,就会根据此配置对内核进行取舍编译。 编译内核之前要先配置。为了正确、合理地设置内核编译配置选项,从而只编译系统需…

BM85 验证IP地址(字符串)

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** 验证IP地址* param IP string字符串 一个IP地址字符串* return string字符串*/public boolean isIPv4(String IP){//没有.i…

单片机入门到精通:一站式在线学习平台!

介绍:单片机,也称为微控制器(MCU),是一种集成了中央处理器(CPU)、随机存储器(RAM)、只读存储器(ROM)以及输入/输出接口于单一芯片上的微型计算机。…

11.测试教程-自动化测试selenium-3

文章目录 1.unittest框架解析2.批量执行脚本2.1构建测试套件2.2用例的执行顺序2.3忽略用例执行 3.unittest断言4.HTML报告生成5.异常捕捉与错误截图6.数据驱动 大家好,我是晓星航。今天为大家带来的是 自动化测试selenium第三节 相关的讲解!&#x1f600…

2024年大模型面试准备(三):聊一聊大模型的幻觉问题

节前,我们组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、参加社招和校招面试的同学,针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何备战、面试常考点分享等热门话题进行了深入的讨论。 合集在这…

羊大师羊奶靠谱么?信誉与持续见证,共筑信赖之选

羊大师羊奶靠谱么?信誉与持续见证,共筑信赖之选 在如今注重健康饮食的时代,羊奶以其丰富的营养价值和独特的风味,逐渐受到了消费者的青睐。在众多羊奶品牌中,羊大师羊奶以其出色的品质、良好的信誉和持续的创新精神&a…

关于「技术开发技能」课程

本课程分为三个部分,带您了解如何使用大模型平台、如何训练与部署大模型及生成式AI产品应用与开发,您将能了解各类服务的优势、功能、典型使用案例、技术概念和成本。 学习任选的两个课程模块,并通过测验者,将授予「技术开发技能…

隆道分享AI技术应用实践 以AI赋能采购业务管理

2024年3月21日-22日,以“面向务实的数字化”为主题的“第12届医药健康行业数字化高峰论坛”在上海举办。本届大会聚焦项目建设、技术创新与应用、新业务模式及收效等话题,探讨AI制药与大模型应用,分享智能化技术在多领域的落地案例。隆道公司…

情感视频素材从哪里找?推荐情感视频素材分享

随着时代变化短视频的兴起,人们越来越喜欢用视频来表达自己的情感和经历。为了满足创作者对于情感视频素材的需求,以下列出了几个素材分享网站,帮助你更好地创作和传达情感,引起大家的共鸣。 蛙学网 作为一家国内知名的素材分享…

python能做什么

python能做什么 Web开发:Python具有许多流行的Web框架,如Django和Flask,使得它成为Web开发的首选语言。它简洁、易于学习、且拥有丰富的生态系统,能够快速构建高性能的Web应用。 数据科学和机器学习:Python在数据科学…

Webpack部署本地服务器

Webpack部署本地服务器 目录 Webpack部署本地服务器目的认识模块热替换(HMR)什么是 HMRHMR 通过如下几种方式, 来提高开发的速度如何使用 HMRhost 配置 目的 完成自动编译 常用方式: webpack-dev-server webpack-dev-server 是一个用于开发环境的 Web 服…

动态规划,二维DP

文章目录 1、摆花2、异或选数3、数字三角形 1、摆花 分析: 输入2 4 3 2 的情况下,只有 (2,2) , (3,1) 这两种方案。 所以,设置状态 dp[i][j] 表示到第 i 种花(共 n 种花)、第 j 个位置(共 m 个位置&#xf…

Leetcode算法题笔记(2)

目录 图论51. 岛屿数量解法一 52. 腐烂的橘子解法一 53. 课程表解法一 54. 实现 Trie (前缀树)解法一 回溯55. 全排列解法一 56. 子集解法一解法二 57. 电话号码的字母组合解法一 58. 组合总和解法一解法二 59. 括号生成解法一解法二 60. 单词搜索解法一 61. 分割回文串解法一 …

[Netty实践] 请求响应同步实现

目录 一、介绍 二、依赖引入 三、公共部分实现 四、server端实现 五、client端实现 六、测试 一、介绍 本片文章将实现请求响应同步,什么是请求响应同步呢?就是当我们发起一个请求时,希望能够在一定时间内同步(线程阻塞&am…

FPGA高端项目:解码索尼IMX327 MIPI相机转HDMI输出,提供FPGA开发板+2套工程源码+技术支持

目录 1、前言2、相关方案推荐本博主所有FPGA工程项目-->汇总目录我这里已有的 MIPI 编解码方案 3、本 MIPI CSI-RX IP 介绍4、个人 FPGA高端图像处理开发板简介5、详细设计方案设计原理框图IMX327 及其配置MIPI CSI RX图像 ISP 处理图像缓存HDMI输出工程源码架构 6、工程源码…

Java中SPI机制简单演示

Java中SPI机制简单演示 写一个SpiService接口 public interface SpiService {void run();}写两个实现类,注意:实现类可以跨包 Slf4j public class SpiServiceImpl1 implements SpiService {Overridepublic void run() {log.warn("SpiServiceImpl…

简单破除github的2FA验证

简单破除github的2FA验证 文章目录 简单破除github的2FA验证👨‍🏫Authenticator工具 👨‍🏫Authenticator工具 最近使用github的时候发现要搞一个2FA的验证才可以 验证的途径有两种:一种是用手机电话验证,…