包含多个段的程序

要使用一段安全的空间,第五章中我们说0:200~0:2ff是相对安全的。可这段代码容量只有256个字节。

合法地通过操作系统取得的空间都是安全的。

程序取得所需空间的方法有两种,一是加载程序的时候程序分配,再就是程序在执行的过程中向系统申请。

对于使用多个段的问题,我们将讨论:
(1)在一个段中存放数据、代码、栈,我们先来体会一下不使用多个段时的情况;
(2)将数据、代码、栈放入不同的段中。


6.1 在代码段中使用数据

考虑这样一个问题,编程计算以下8个数据的和,结果存在ax寄存器中:
0123h、0456h、0789h、0abch、0defh、0fedh、0cbah、0987h
我们如何去寻找这个内存段的空间呢?(这里有代码段和数据段)

从规范的角度来讲,我们不能自己随便决定哪段空间可以使用,应该由系统来分配。我们可以在程序中,定义我们希望处理的数据,这些数据就会被编译、连接程序作为程序的一部分写到可执行文件中。当可执行文件中的程序被加载入内存时,这些数据也同时被加载入内存中。与此同时,我们要处理的数据也就自然而然地获得了存储空间。

看具体程序:

assume cs:code
code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h   ;dw代表是字型数据mov bx,0mov ax,0mov cx,8
s:  add ax,cs:[bx]add bx,2loop smov ax,4c00hint 21hcode ends
end

编译、连接这段程序后,我们看到如下:

显然,我们程序从cs:ip开始,而cs开始部分就是数据部分。明显是我们程序在代码段的dw影响了这段代码开始执行的位置(更准确的说,是我们没有定义数据段)。

那么,我们怎样让程序正确的(或说cs:ip)指向程序入口呢?如下:

assume cs:code
code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hstart:  mov bx,0mov ax,0mov cx,8
s:      add ax,cs:[bx]add bx,2loop smov ax,4c00hint 21hcode ends
end start

如上代码所看到的,我们在两处加了start

可执行文件中的程序执行过程如下:

  1. 由其他的程序(Debug、command或其他程序)将可执行文件中的程序加载入内存;
  2. 设置CS:IP指向程序的第一条要执行的指令(即程序的入口),从而使程序得以运行;
  3. 程序运行结束后,返回到加载者。

现在的问题是:我们由什么来判定程序入口呢?具体框架如下


6.2 在代码段中使用栈

完成下面的程序,利用栈,将程序中定义的数据逆序存放。

assume cs:code
code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h?   mov ax,4c00hint 21hcode ends
end

程序思路:定义的数据存放在cs:0~f单元中,我们只要将数据依次入栈,再依次出栈就可以逆序存放了。

问题是:我们首先要有一段可当作栈的内存空间。如下:

assume cs:code
code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hdw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;用dw定义16个字型数据,在程序加载后,将取得16个字的;内存空间,存放这16个数据。后面的程序段中将这段空间;当作栈来使用start:  mov ax,csmov ss,axmov sp,30h  ;将设置栈顶ss:sp指向cs:30mov bx,0mov cx,8s:      push cs:[bx]add bx,2loop s      ;将代码段0~15单元中的8个字型数据依次入栈mov bx,0mov cx,8s0:     pop cs:[bx]add bx,2loop s0mov ax,4c00hint 21hcode ends
end start

自此,我们的程序段定义并且使用了,发现很麻烦。

检测点 6.1

(1)下面程序实现依次使用内存0:0~0:15单元中的内容改写程序中的呃数据,完成程序:

assume cs:code
code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hstart:  mov ax,0mov ds,axmov bx,0mov cx,8
s:      mov ax,[bx]mov cs:[bx],ax   ;题目这段代码为空,需要自己填写add bx,2loop smov ax,4c00hint 21hcode ends
end start

(2)下面的程序实现依次内存0:0~0:15单元中的内容改写程序中的数据,数据的传送用栈来进行。栈空间设置在程序内。完成程序:

assume cs:code
code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hdw 0,0,0,0,0,0,0,0start:  mov ax,cs   ;题目ax后面为__mov ss,axmov sp,20h  ;题目ss后面为__mov ax,0mov ds,axmov bx,0mov cx,8s:      push [bx]pop cs:[bx] ;题目为________add bx,2loop smov ax,4c00hint 21hcode ends
end start

6.3 将数据、代码、栈放入不同的段

在前面的内容中,我们在程序中用到了数据和栈,将数据、栈和代码都放在了一个段里面。

这样做显然有两个问题:
(1)把它们放在一个段中使程序显得混乱
(2)前面程序中处理的数据很少,用到的栈空间也很小,加上没有很长的代码,放到一个段里面没有问题。但如果数据、栈和代码需要的空间超过64KB,就不能放在一个段中。

所以,应该考虑用多个段存放数据、栈和代码。如下所示:

assume cs:code,ds:data,ss:stack;数据段
data segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends;栈段
stack segmentdw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends;代码段
code segmentstart:  mov ax,stackmov ss,axmov sp,20h      ;设置栈顶ss:sp指向stack:20mov ax,datamov ds,axmov bx,0        ;设置ds:bx指向data段的第一个单元mov cx,8
s:      push [bx]add bx,2loop s          ;以上将data段中的0~15单元中的8个字型数据一次入栈mov bx,0mov cx,8
s0:     pop [bx]add bx,2loop s0         ;以上依次出栈8个字型数据到data段的0~15单元中mov ax,4c00hint 21hcode endsend start

程序说明:
(1)定义多个段的方法
定义一个段的方法和前面所讲的定义代码段的方法没有区别,只是对于不同的段,要有不同的段名。
(2)对段地址的引用
现在,程序中有多个段了,如何访问段中的数据呢?当然要通过地址,而地址是分为两部分,即段地址和偏移地址。如何指明要访问的数据的段地址呢?在程序中,段名就相当于一个标号,它代表了段地址。(形如:mov ax,data)
(3)“代码段”、“数据段”、“栈段”完全是我们的安排

  1. 我们在源程序中为这三个命名为code、stack、data
  2. 我们在源程序中用伪指令“assume cs:code,ds:data,ss:stack”将它们关联起来
  3. 若要CPU按我们的安排行事,就要用机器指令控制它,源程序中的汇编指令是CPU要执行的内容。CPU如何知道执行它们?我们在源程序的最后用“end start”说明程序的入口,这个入口将被写入可执行文件描述信息,可执行文件的程序被加载入内存后,CPU的CS:IP被设置指向这个入口,从而开始执行程序中的第一条指令。

实验 5 编写、调试具有多个段的程序

(1)将下面的程序编译连接,用Debug加载、跟踪,然后回答这个问题。

assume cs:code,ds:data,ss:stackdata segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data endsstack segmentdw 0,0,0,0,0,0,0,0
stack endscode segment
start:  mov ax,stackmov ss,axmov sp,16mov ax,datamov ds,axpush ds:[0]push ds:[2]pop ds:[2]pop ds:[0]mov ax,4c00hint 21hcode ends
end start

1.CPU执行程序,程序返回前,data段的数据为多少?

2.CPU执行程序,程序返回前,cs=?、ss=?、ds=?。

3.设置程序加载后,code段的段地址为X,则data段的段地址为?,stack段的段地址为?。
code=X、data=X-20、stack=X-10。

(2)将下面的程序编译连接,用Debug加载、跟踪,然后回答问题。

assume cs:code,ds:data,ss:stackdata segmentdw 0123h,0456h
data endsstack segmentdw 0,0
stack endscode segment
start:  mov ax,stackmov ss,axmov sp,16mov ax,datamov ds,axpush ds:[0]push ds:[2]pop ds:[2]pop ds:[0]mov ax,4c00hint 21hcode ends
end start

1.CPU执行程序,程序返回前,data段中的数据为多少?

2.CPU执行程序,程序返回前,cs=?、ss=?、ds=?。

3.设程序加载后,code段的段地址为X,则data段的段地址为?,stack段的段地址为?。
cs = X , ds = X-20, ss = X-10。
4.对于如下定义的段:
name segment
···
name ends
如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为?。
N/256取上整

(3)将下面的程序编译连接,用Debug加载、跟踪,然后回答问题。

assume cs:code,ds:data,ss:stackcode segment
start:  mov ax,stackmov ss,axmov sp,16mov ax,datamov ds,axpush ds:[0]push ds:[2]pop ds:[2]pop ds:[2]mov ax,4c00hint 21hcode endsdata segmentdw 0123h,0456h
data endsstack segmentdw 0,0
stack endsend start

1.CPU执行程序,程序返回前,data段中的数据为多少?

2.CPU执行程序,程序返回前,cs=?、ss=?、ds=?。

3.设程序加载后,code段的段地址为X,则data段的段地址为?,stack的段地址为?。
code=X , data=X+(code指令字节数/256)取上整+1 , stack = data + 1。

(4)如果将(1)(2)(3)题中的最后一条伪指令“end start”改为“end”(也就是说,不指名程序的入口),则哪个程序仍然可以正确执行?请说明原因。

第3个可以,首先是指令从何处开始,3可以正确的指向指令开始出,而其他两个不行;其次,是指令结束,3个都可以正常结束,因为只要遇到mov ax,4c00h和int 21h执行完后,程序就返回了。

(5)程序如下,编写code段中的代码,将a段和b段中的数据依次相加,将结果存到c段中。

assume cs:codea segmentdb 1,2,3,4,5,6,7,8
a endsb segmentdb 1,2,3,4,5,6,7,8
b endsc segmentdb 0,0,0,0,0,0,0,0
c ends
;题目code需要自己编写
code segment
start:mov ax,cmov ds,axmov bx,0mov ax,amov es,axmov cx,8s:  mov dl,0add dl,es:[bx]add dl,es:[bx+16]mov [bx],dlinc bxloop smov ax,4c0hint 21hcode ends
end start

实验结果如下:

(6)程序如下,编写code段中的代码,用push指令将a段中的前8个字型数据,逆序存储到b段中。

assume cs:codea segmentdw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0fh,0ffh
a endsb segmentdw 0,0,0,0,0,0,0,0
b ends
;题目代码段需要自己编写
code segment
start:mov ax,bmov ss,axmov sp,16mov ax,amov ds,axmov bx,0s:  push [bx]add bx,2loop smov ax,4c00hint 21hcode ends
end start

实验结果如下:


本章完

包含多个段的程序---汇编学习笔记相关推荐

  1. 第一个程序---汇编学习笔记

    第四章 第一个程序 4.1 一个源程序从写出到执行的过程 一个汇编语言程序从写到最终执行的简要过程. 编写汇编源程序 对源程序进行编译连接 执行可执行文件中的程序 如图所示: 4.2 源程序 程序代码 ...

  2. 包含多个段的程序01 - 零基础入门学习汇编语言29

    第六章:包含多个段的程序01 让编程改变世界 Change the world by program 引言 前面我们写的程序中,只有一个代码段. 现在有一个问题是: 如果程序需要用其他空间来存放数据, ...

  3. 《汇编语言》第6章 -包含多个段的程序 检测点答案,实验5,总结

    第6章:包含多个段的程序 1.在代码段中使用数据 "dw":define word(定义字型数据:) "db"(定义字节型数据:) "start&qu ...

  4. 汇编学习笔记——伪指令

    目录 伪指令 段定义 结束标记 段关联标记 数据定义 标号 offset指令 seg指令 地址标号 数据标号 代码分段 程序标识 多文件系统 字符输入 重复定义 注释 重复汇编伪指令 伪指令汇总 伪指 ...

  5. 汇编学习笔记——汇编指令

    目录 汇编指令 nop指令 mov.add.sub指令 adc.sbb指令 and.or指令 移位指令 逻辑左/右移指令 循环左/右移指令 算术左/右移指令 带进位循环左/右移指令 inc指令 pus ...

  6. GTK+图形化应用程序开发学习笔记(五)—组装盒、组合表、固定容器构件

    GTK+图形化应用程序开发学习笔记(五)-组装盒.组合表.固定容器构件 一.组装盒 组装盒(GtkBox)也称为组合构件.使用组装盒可以将多个构件放在一个容器中.容器可以把组装盒看作是一个构件.不像按 ...

  7. GTK+图形化应用程序开发学习笔记(一)—概述

    GTK+图形化应用程序开发学习笔记(一)-概述 一.什么是GNOME. GNOME的意思是"GNU Network Object Model Environment"(GNU网络对 ...

  8. 【前端学习笔记】移动web-黑马程序员学习笔记

    移动web-黑马程序员学习笔记 1 字体图标 2 平面转换 2.1 绝对定位元素居中: 2.2 双开门效果 2.3 旋转效果 2.4* 转换原点 2.5 多重转换效果 2.6 缩放 3* 渐变 4 空 ...

  9. 汇编学习笔记:对抗反汇编实验2019092801

    汇编学习笔记:对抗反汇编实验2019092801 实验描述 实验环境 实验过程 实验结论 实验描述 使用相连的jz和jnz指令跳转到紧接着jnz指令的call指令的第二个字节.call指令实际上无效. ...

最新文章

  1. 10.2.2移动产品离线功能等具体解释----暨4月8日移动《在离线一体化》公开课Qamp;A...
  2. Apache OFBIZ高速上手(二)--MVC框架
  3. c++ STL 工程实践的15条建议
  4. Macbook pro wifi连接无线路由不稳定掉线的解决办法
  5. 每天进步一点点《ML - 逻辑回归》
  6. Vue中基于Vuex使用echarts组件动态数据绑定的方法
  7. Asp.Net中global.asax文件的描述
  8. qbittorrent container 改共享文件_SSH连接docker中的container
  9. 如何帮助企业把风控做得更好?
  10. Cocos2d-x v3.2笔记——总结Cocos2d-x 3.x版本的一些变化
  11. FPGA + labwindows/CVI 2017 串口通信 电子钟
  12. android上传速度测试,使用Android获取当前的互联网速度(移动和Wifi)
  13. 如何获取免费的数字货币历史数据
  14. 对于阿里云的oss上传本地图片的相关注意点
  15. Android接入极光推送,接入华为,小米,OPPO,VIVO厂商通道
  16. 学习笔记2022.7.25-7.30
  17. 默的各种写法图片_默字的意思、默的繁体字、默的笔顺笔画、默字部首和繁体字默的意思...
  18. 让字母自增,就像A-Z,Z后面就是AA-AZ,然后BA-BZ...
  19. 720度全景带你vr云游景区,vr云游在景区的应用优势
  20. RiskCloud-基于Markov算法精准的SIL验证模块

热门文章

  1. PHP实现四位数字+字母验证码
  2. 170728、单例模式的三种水平代码
  3. Unity -----一些可能存在的错误
  4. LWIP裸机环境下实现TCP与UDP通讯
  5. linux Ubuntu apache2 伪静态设置
  6. InvokeHelper,让跨线程访问/修改主界面控件不再麻烦(转)
  7. 山寨一把QQ移动终端聊天框,网页版效果其实也很好的!
  8. 开发者福利:三款 iOS 应用原型开发工具
  9. 《博客园精华集》Sharepoint+MOSS分册
  10. 机器学习中常见的损失函数