汇编语言学习assume的作用详解

assume 的作用是关联段名与段寄存器。

如果你在数据段中定义了变量名,比如:

x   db  0

而你在代码中,需要直接使用这个变量名,比如:

mov   al,  x

那么,汇编程序在汇编时,就会报告错误。

因为,mov指令中遇到 x 这个变量名时,汇编程序不知道它要用哪个段寄存器作为段地址。

所以:

若要用变量名直接访问,或使用语句标号(比如你例子中的标号 start)就必须要在assume伪指令中将这些变量或标号所在段的段名,与段寄存器名关联,否则会出错。

如果你不使用段中的变量名,可以不关联这个段的段名与寄存器。

如果你访问变量时,都指定了段跨越前缀,关联也不是必须的。比如你可以用 mov al, ds:x访问变量 x 。

这几天在看王爽大大的 汇编语言。对于assume伪指令却很是不懂。

比如已经定义了assume cs:code,ds:data

但用debug观察的时候,发现ds段寄存器却没有相关联的数据。

必须在cs中写明: mov ax,data

                            mov ds,ax
然后才能发现ds中有正确的数据。

于是疑惑,assume不是已经关联了ds嘛?

上网求助 = =、 然后找到答案。

编写程序,是写给编译软件的。由编译软件,编译成机器码,再去控制CPU。但是,编译软件,对assume语句,并不生成机器码。

所以,必须有mov ax,data,mov ds,ax,CPU才能受控。

---assume语句,是伪指令,仅仅是写给编译软件的。编译软件,并不把它生成机器码。

assume对除了CS以外的其它段寄存器,仅仅只是关联了段名,以便在访问段内变量时程序可以知道用哪个段寄存器,并没有在程序加载时将段地址装入段寄存器。

所以,将段地址装入段寄存器的工作,必须由用户在程序中自己编写代码,并在程序开始运行时执行代码完成装入工作。
仅仅对CS段寄存器,会在关联段名的同时,在程序加载时自动将段地址装入段寄存器。
----补充:前天知道了答案后,我以为assume ds:data 之类的指没有什么用,只是给程序员看的。

但今天发现不是这样的。 如果你在data中用了标号的话,则assume ds:data不能省略。

比如:

data segment
a db 1,2,3,4 ,5,6,7,8
b dw 0
data ends

a,b的后面没有“ :”。

如果你想在cs段中用数据标号访问数据,则必须在开头加上assume ds:data,否则会报错

Arror A2068:Can not address with segment register

不过就算在开头加上了assume ds:data,代码段中也不能少了mov ax,data,mov ds,ax。

作用:用于标识默认段前缀

解释:assume 并不能改变ds等段寄存器的值,但他能改变编译器产生的汇编代码。比如:

assume ss:stack

stack segment

x :db 0

stack ends

如果程序需要mov ax,[x],那么程序如何定位[x]呢?我们知道x只是一个偏移地址0,所以此时assume就相当于告诉编译器stack段的所有标号都与ss相关联,所以此时[x]就相当于ss:[0].如果我们直接将这句改为mov ax,ss:[0],那么前面不加assume也是可以的.这也是为什么[0]被编译器强制理解为立即数,而[标号]却被理解为标号里的内容的原因,因为标号必须与段assume,否则会报错cannot address with segment register.而[0]无默认段,就只能被认为为立即数了.

所以,我们仍需在程序中将ss的值,用指令修改为stack,原因就是assume并不会修改段寄存器,这个由dos系统决定,如果dos系统决定将段值编译进.exe文件头,并在加载进内存时根据文件头,修改段值,那么此时assume就相当于可以改变段值了.但是我调试的现实是ds、es指向psp头(psp详见16位exe程序加载过程),ss指向ds+0:00f0,cs指向ds+0:0100。

以上就是汇编语言学习assume的作用详解的详细内容,更多关于汇编语言assume作用的资料请关注我们其它相关文章!

(0)

相关推荐

  • 详解汇编语言各种指令的解释与用法

    [数据传输指令] 一.通用数据传送指令 1.传送指令MOV(move) 指令的汇编格式:MOV DST,SRC 指令的基本功能:(DST)<-(SRC) 将原操作数(字节或字)传送到目的地址.指令支持的寻址方式:目的操作数和源操作数不能同时用存储器寻址方式,这个限制适用于所有指令.指令的执行对标志位的影响:不影响标志位.指令的特殊要求:目的操作数DST和源操作数SRC不允许同时为段寄存器:目的操作数DST不能是CS,也不能用立即数方式. 2.进栈指令 PUSH(push onto the sta

  • 汇编语言功能字符串大小写转换实现实例详解

    目录 问题1:将data段中的第一个字符串转换成大写,第二个字符串转换成小写 问题2:将data段中每个单词的头一个字母改成大写字母 问题3:将data段中每个单词改为大写字母 问题4:将data段中每个单词的前4个字母改为大写字母 问题5:设计一个子程序,将一个全是字母的字符串转化成大写 问题6:设计一个子程序,将一个全是字母,以0结尾的字符串,转化成大写 复杂一点的对结构化数据的版本 问题1:将data段中的第一个字符串转换成大写,第二个字符串转换成小写 分析: 如何转换成大小写 如果利用A

  • 汇编基础程序编写教程示例

    目录 源程序 1.1 构成 寄存器与段的关联假设 标号 定义一个段 程序结束标记 程序返回 程序运行 1.2 源程序中的"程序" 1.3 段结束.程序结束.程序返回 1.4 语法错误和逻辑错误 2 程序执行的过程 2.1 一个汇编语言程序从写出到最终执行的简要过程: 2.2 连接 2.3 可执行文件 2.4 程序执行过程的跟踪 总结 3 程序编写 3.1 两个基本的问题 3.2 数据在哪里 立即数(idata) 寄存器 段地址(SA)和偏移地址(EA) 3.3 指令处理的数据有多长 3

  • 汇编语言功能用循环累加实现乘法

    目录 问题1:编程计算2的2次方,结果存在ax中 分析:用2+2实现 问题2:编程实现2的12次方 分析:用loop实现 问题3:编程实现123*236,结果存在ax中 分析:用236相加123次的计算次数比较少,节约计算资源 问题4:计算ffff:0006单元中的数乘以3,结果存储在dx中 1.判断数据是否能够存储 2.判断数据相加是否能够位数相同 问题5:计算ffff:0~ffff:b单元中的数据的和,结果存储在dx中 1.运算的结果是否超出寄存器的范围 2.能否直接相加dx中的数据 问题6

  • 汇编语言学习assume的作用详解

    assume 的作用是关联段名与段寄存器. 如果你在数据段中定义了变量名,比如: x db 0 而你在代码中,需要直接使用这个变量名,比如: mov al, x 那么,汇编程序在汇编时,就会报告错误. 因为,mov指令中遇到 x 这个变量名时,汇编程序不知道它要用哪个段寄存器作为段地址. 所以: 若要用变量名直接访问,或使用语句标号(比如你例子中的标号 start)就必须要在assume伪指令中将这些变量或标号所在段的段名,与段寄存器名关联,否则会出错. 如果你不使用段中的变量名,可以不关联这个

  • JS中的防抖与节流及作用详解

    概念 函数防抖(debounce)是指在一定时间内,在动作被连续频繁触发的情况下,动作只会被执行一次,也就是说当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间,所以短时间内的连续动作永远只会触发一次,比如说用手指一直按住一个弹簧,它将不会弹起直到你松手为止. 函数节流是指一定时间内执行的操作只执行一次,也就是说即预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期,一个比较形象的例子是如果将水龙头拧紧直到水是以水滴的形式流出

  • 汇编语言实现电子闹钟思路详解

    2.1 设计思路 首先使用8255.8254.8259 三个芯片实现电子时钟的功能,让闹钟可以正常走时:其次,在时钟的基础上添加闹铃功能.整点报时功能.设置当前时间功能:完成设计. 2.2 设计方案 1. 电子时钟部分:此次设计是通过对计数器8254设定计数值对脉冲进行计数,在程序里,8254工作于计数器0,方式3.接入的CLK为1MHz,设计数初值为10000,每100次中断计数一次,产生的记数时间正好是时钟每秒走过的时间.通过对中断控制器8259设置初始化命令字初值来控制中断.程序中通过移位

  • Java中反射机制和作用详解

    前言 很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象. 那么接下来大师就带你们了解一下反射是什么,为什么要学习反射? 下面我们首先通过一个实例来说明反射的好处: 方法1.不用反射技术,创建用户对象,调用sayHello方法 1.1 我们首先创建一个User类 package com.dashi; /** * Author:Java大师 * User对象,包含用户的id和姓名以及sayHello方法 */ public

  • Python OpenCV学习之图像滤波详解

    目录 背景 一.卷积相关概念 二.卷积实战 三.均值滤波 四.高斯滤波 五.中值滤波 六.双边滤波 七.Sobel算子 八.Scharr算子 九.拉普拉斯算子 十.Canny算法 背景 图像滤波的作用简单来说就是将一副图像通过滤波器得到另一幅图像:明确一个概念,滤波器又被称为卷积核,滤波的过程又被称为卷积:实际上深度学习就是训练许多适应任务的滤波器,本质上就是得到最佳的参数:当然在深度学习之前,也有一些常见的滤波器,本篇主要介绍这些常见的滤波器: 一.卷积相关概念 卷积核大小一般为奇数的原因:

  • Python学习之循环方法详解

    目录 for循环 while循环 拓展:列表推导式 常见的推导式方法 循环的继续与退出(continue与break) continue的使用 break的使用 循环实现九九乘法表 什么是循环? —> 循环是有着周而复始的运动或变化的规律:在 Python 中,循环的操作也叫做 ‘遍历’ . 与现实中一样,Python 中也同样存在着无限循环的 方法与有限循环的方法.接下来我们就先看看有限循环的方法 —> for 循环 for 循环 for 循环的功能:通过 for 关键字将列表.元组.字符串

  • Python学习之面向对象编程详解

    目录 什么是面向对象编程(类) 类的关键字-class 类的定义与使用 类的参数-self self的解析与总结 类的构造函数 构造函数的创建方法 关于对象的生命周期 什么是面向对象编程(类) 利用(面向)对象的(属性和方法)去进行编码的过程即面向对象编程 自定义对象数据类型就是面向对象中的类(class)的概念 类的关键字 - class class 关键字用来声明类,类的名称首字母大写,多单词的情况下每个单词首字母大写(即驼峰命名法).在我们一开始学习 Python 的时候说过,要尽量避免使

  • Python学习之日志模块详解

    目录 日志的作用 日志的等级 logging 模块的使用 logging 模块演示小案例 OK,今天我们来学习一下 python 中的日志模块,日志模块也是我们日后的开发工作中使用率很高的模块之一,接下来们就看一看今天具体要学习日志模块中的那些内容吧. 日志的作用 说到日志,我们完全可以想象为现实生活中的日记.日记是我们平时记录我们生活中点点滴滴的一种方法,而日志我们可以认为是 程序的日记 ,程序的日记是用来记录程序的行为,一般来说我们可以通过日志记录一些程序的重要信息. 比如哪里报错了?报错原

  • Python学习之虚拟环境原理详解

    目录 认识虚拟环境 Python中的虚拟环境工具 Virtualenv Treminal 终端演示 该章节我们学习虚拟环境的相关知识,虚拟环境对于刚刚使用Python的初学者来说使用的概率可能会比较低.但是我们依然要对它有一定的了解. 认识虚拟环境 在我们平时的工作环境中,可能会存在一台电脑存在多个版本的 python 的情况 . 比如我们有一个 Python2.7的版本,还有一个 Python3.8的环境,它们两个都存在与我们当前的系统中.这就造成了一个问题,两个版本都在同一个环境下,造成 p

  • opencv调用yolov3模型深度学习目标检测实例详解

    目录 引言 建立相关目录 代码详解 附源代码 引言 opencv调用yolov3模型进行深度学习目标检测,以实例进行代码详解 对于yolo v3已经训练好的模型,opencv提供了加载相关文件,进行图片检测的类dnn. 下面对怎么通过opencv调用yolov3模型进行目标检测方法进行详解,付源代码 建立相关目录 在训练结果backup文件夹下,找到模型权重文件,拷到win的工程文件夹下 在cfg文件夹下,找到模型配置文件,yolov3-voc.cfg拷到win的工程文件夹下 在data文件夹下

随机推荐