汇编语言综合研究试验3--使用内存空间

寄存器只有十几个,但是内存空间可以很大,对于内存空间来说,要使用它们,一般都需要给出2个信息:
1>指明是存储空间所在、是哪个的信息
2>指明存储空间有多大的类型信息

下面我们来完成本次试验

一.实验过程

1.在tc.exe中编辑程序um1.c,保存到c:\minic下,编译,连接,生成um1.exe,用debug加载um1.exe,对mian函数(01fa)的汇编代码进行分析,找到每条c语句对应的汇编代码
在这里插入图片描述
在这里插入图片描述
*(char *)0x2000 = ‘a’; -> mov byte ptr ds:[2000h],‘a’
*(int *)0x2000 = 0xf; -> mov word ptr ds:[2000h],000Fh
*(char far *)0x20001000 = ‘a’; -> mov bx,2000h
mov es,bx
mov bx,1000h
mov byte ptr es:[bx],‘a’
_AX = 0x2000; -> mov ax,2000h
*(char *)_AX = ‘b’; -> mov bx,ax
mov byte ptr [bx],‘b’
_BX = 0x1000; -> mov bx,1000h
(char )(_BX+_BX) = ‘a’; -> add bx,bx
mov byte ptr ds:[bx],‘a’
(char far)(0x20001000+_BX)=
(char
)_AX; ->
mov bx,ax
mov al,[bx]
xor cx,cx
add bx,1000h
adc cx,2000h
mov es,cx
mov es:[bx],al

可以看到,对应语句的汇编代码

2.根据第一小问展示的汇编代码,可以编写一个在屏幕中间显示一个绿色的字符‘a’d的程序,可以像汇编一样通过写显存来显示字符

main()
{
_BX=80*24+40*2;
*(char far *)(0xb8000000+_BX)='a';
*(char far *)(0xb8000000+_BX+1)=0x2;
}

在这里插入图片描述
3.分析第三小问的汇编代码,由截图可以看出,编译器对于变量进行了不同的处理
对于全局变量a1,a2,a3,编译器将它保存在了ds:[01A6]开始的内存中,所有函数都可以直接访问该内存
对于局部变量b1,b2,b3,编译器将它保存在了栈中

“push bp”,将bp寄存器入栈,暂存bp寄存器
“mov bp,sp”,将sp寄存器暂存在bp中
这两条语句应该是用来方便局部变量入栈的
在这里插入图片描述
在这里插入图片描述
4.分析第四小问的汇编代码,可以看到,在call指令结束后,有一条指令“mov [bp-02],ax”,编译器会使用ax传递返回值,并入栈

在这里插入图片描述
在这里插入图片描述

5.分析malloc函数
1>程序通过宏定义将Buffer定义为((char )(int far *)0x02000000) 。Buffer可以认为存放在0200h:0000的一个指针,那么对Buffer的操作就是对该地址的操作。那么Buffer[10]就是Buffer地址加上10后的地址

2>Buffer = (char *)malloc(20); 表示使用malloc申请一个20个字节的空间,返回的指向申请的空间的指针强制转换成char型指针后赋值给Buffer,由a中分析知,也就是放置到0200h:0000开始的两个字节空间中,该地址指向向系统申请的内存首地址

3>Buffer[10] = 0; Buffer[10] != 8 与 Buffer[10]++; 这两条语句比较容易理解,由a中的分析可知,分别是对申请的内存地址+10的内存单元进行赋值为0,判断是否为8,和自加1的操作

4>while循环前将Buffer[10]置0,循环中每次判断Buffer[10]是否为8,执行完Buffer[Buffer[10]] = ‘a’+Buffer[10] 后将Buffer[10]] 自加1,可见Buffer[10]] 在循环中充当计数器的角色。循环的功能是将Buffer[Buffer[10]] = ‘a’+Buffer[10] 执行八次。

5>Buffer[Buffer[10]] = ‘a’+Buffer[10] 表示将计数器取出(0-7)加上字符a,随着计数器变化,a的变化为(a-h)。并赋值给Buffer[Buffer[10]],表示取出计数器,根据计数器的值在Buffer寻址,那么变化为Buffer[0]到Buffer[7]。可以分析处程序的功能是对Buffer[0]到Buffer[7]的内存写入a到h

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Debug+u命令查看01fa开始处的汇编代码

二.总结思考

malloc函数申请的内存在什么地方?
因为c中函数是通过ax传递返回值的,查看函数返回后寄存器的状态(call指令之后)
在这里插入图片描述
运行前查看0580h
在这里插入图片描述
运行后查看0580h
在这里插入图片描述

在这里插入图片描述

可以看到,已经成功写入

由上述分析,可知,malloc()函数申请的内存实质是通过ax返回一个偏移地址,段地址为ds,malloc()申请的内存不是位于栈里,函数返回后相应的内存空间也不会被回收,必须由程序员调用free()来回收这段内存,以免造成内存泄露

三.研究体会

这次实验一共研究了5个小问题,首先需要清楚怎么利用内存空间(给出内存空间地址和大小),学习使用内存空间,局部变量的内涵,全局变量的内涵,返回值的实现。拿研究C语言后的汇编知识在反观汇编程序的实现,会有更深入的理解,更结构化的编程概念。

综合研究阶段所需要的tc2.0我已经上传网盘,免费分享给大家,关注我的公众号,菜单栏–>技术相关–>免费资源即可领取,还有网课查答案,包括学习通、智慧树、mooc,内容涵盖计算机、政治等等,还有其他免费资源(简历模板、电子版书籍和考试资料等等),说不准大家会有用(分享干货)!

扫码加关注吧!

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值