汇编语言入门:一段安全的段空间
2018-02-15 10:31
197 查看
要知道,内存空间时不能随意随意读写的,因为可能会触及操作系统内存,这就是“不安全”的做法,是一次不合法的行为
段前缀:我们可以通过“段前缀”指令来认为更改默认的段寄存器
例如:
我们可以这样显式的指定我们要的段地址:
对于8086CPU,段地址寄存器有DS、CS、ES、SS
同样记住,我在学习汇编语言,要使用它来获得底层的编程体验,理解计算机底层的基本工作原理,所以我们要尽量直接对硬件编程而不去理会操作系统
在纯DOS(实模式)下,可以不理会DOS而直接使用汇编语言去操作真实的硬件,因为运行在CPU实模式下的ODS没有能力对硬件系统进行全面、严格地管理;但是在Windows 2000、Unix这些运行于CPU保护模式下的操作系统中,是无法忽视操作系统的存在的,硬件已经被这些操作系统利用CPU保护模式所提供的功能全面而严格地管理了
一段安全的空间:在一般的PC机中,DOS方式下,DOS和其它合法的程序一般都不会使用
(至于为啥这256个字节空间是安全的,以后再讲~)
So……以后当我们需要直接向一段内存中写入一段内容时,就使用
![](https://img-blog.csdn.net/20180215095354680?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWJjXzEyMzY2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
(看图,debug模式下0:200内存确实没有数据……)
谜面:请将内存fff:0~fff:b单元中的数据拷贝到0:200~0:20b单元中(汇编实现)
分析:将目标地址0:200~0:20b看成0020:0~0020:b,和源地址单元的偏移地址从同一数值开始(减少寄存器的使用)
谜底:
上面因为源单元FFFF:X和目标单元0020:X相距大于64K(一个段的最大长度)所以每次循环要用两次即设置两次DS的值(现从源地址获取数据,再往目标地址写入数据)
BUT!上面的做法效率不高,可以使用不同的段地址寄存器!
改进版的谜底:
补充:段前缀
在这之前,先说另一个知识点:段前缀:我们可以通过“段前缀”指令来认为更改默认的段寄存器
例如:
mov AX, [0]和
mov AX, DS:[0]是等价的(默认为DS)
我们可以这样显式的指定我们要的段地址:
mov AX, ES:[0]:段地址在ES中,偏移地址为0
对于8086CPU,段地址寄存器有DS、CS、ES、SS
一段安全的段空间
永远记住,我们是在操作系统的环境中工作,操作系统管理所有的资源,当然也包括内存,如果我们需要向内存空间写入数据的话,要使用操作系统给我们分配的空间,而不应直接使用任意指定的内存单元向里面写数据同样记住,我在学习汇编语言,要使用它来获得底层的编程体验,理解计算机底层的基本工作原理,所以我们要尽量直接对硬件编程而不去理会操作系统
在纯DOS(实模式)下,可以不理会DOS而直接使用汇编语言去操作真实的硬件,因为运行在CPU实模式下的ODS没有能力对硬件系统进行全面、严格地管理;但是在Windows 2000、Unix这些运行于CPU保护模式下的操作系统中,是无法忽视操作系统的存在的,硬件已经被这些操作系统利用CPU保护模式所提供的功能全面而严格地管理了
一段安全的空间:在一般的PC机中,DOS方式下,DOS和其它合法的程序一般都不会使用
0:200~0:2ff的
256个字节空间,所以这段空间是安全的
(至于为啥这256个字节空间是安全的,以后再讲~)
So……以后当我们需要直接向一段内存中写入一段内容时,就使用
00200H~002FFH这段空间
(看图,debug模式下0:200内存确实没有数据……)
段前缀的使用
举个栗子如何:^ - ^谜面:请将内存fff:0~fff:b单元中的数据拷贝到0:200~0:20b单元中(汇编实现)
分析:将目标地址0:200~0:20b看成0020:0~0020:b,和源地址单元的偏移地址从同一数值开始(减少寄存器的使用)
谜底:
assume CS:code code segment mov BX, 0 ;(BX)=0偏移地址从0开始 mov CX, 12 ;(CX)=12,循环12次 s:mov AX, 0FFFH ;为DS赋值做准备 mov DS, AX ;(DS)=0FFFH,准备从“源段”读取数据 mov DL, [BX] ;(DL)=((DS)*16+(BX)),将FFFF:BX中的数据送入DL mov AX, 0020H ;为DS赋值做准备 mov DS, AX ;(DS)=0020H,准备向“目标段”传送数据 mov [BX], DL ;((DS)*16+(BX))=(DL),将源数据送入目标单元 inc BX ;(BX)=(BX)+1 loop s mov AX, 4C00H int 21H code ends end
上面因为源单元FFFF:X和目标单元0020:X相距大于64K(一个段的最大长度)所以每次循环要用两次即设置两次DS的值(现从源地址获取数据,再往目标地址写入数据)
BUT!上面的做法效率不高,可以使用不同的段地址寄存器!
改进版的谜底:
assume CS: code code segment mov AX, 0FFFFH ;看吧 mov DS, AX ;这四行 mov AX, 0020H ;分别使用两个不同的段寄存器 mov ES, AX ;DS和ES(转下) mov BX, 0 mov CX, 12 s:mov DL, [BX] ;于是每次循环 mov ES:[BX], DL ;显示的指定前缀(因为不是默认的DS) inc BX loop s ;只需要改变偏移地址(BX),而不需要改变段地址的值了 mov AX, 4C00H int 21H code ends end
相关文章推荐
- [汇编语言]-第五章段前缀及使用 一段安全的空间
- 汇编 | 一段安全的空间
- 汇编学习笔记-一段安全的空间及段前缀的使用.
- 包含多个段的程序01 - 零基础入门学习汇编语言29
- 更灵活的定位内存地址的方法01 - 零基础入门学习汇编语言32
- 数据处理的两个基本问题01 - 零基础入门学习汇编语言38
- 数据处理的两个基本问题03 - 零基础入门学习汇编语言40
- 数据处理的两个基本问题05 - 零基础入门学习汇编语言42
- 外中断01 - 零基础入门学习汇编语言69
- 汇编语言: 试编写一段程序,从键盘接收一个-32768-32767 间的十进制有符号数,并在终端上 显示与它等值的二进制数。
- Call指令和Ret指令讲解02 - 零基础入门学习汇编语言49
- 直接定址表01 - 零基础入门学习汇编语言72
- 汇编语言入门:将数据、代码、栈放入不同的段
- 直接定址表02 - 零基础入门学习汇编语言73
- 一本Linux下AT&T汇编语言与GCC内嵌汇编入门的中文书籍
- 汇编语言---关于自定义的段占用内存空间
- 汇编语言入门:转移指令(二)
- 汇编语言入门教程
- 内中断01 - 零基础入门学习汇编语言60
- 寄存器(内存访问)05 - 零基础入门学习汇编语言17