从汇编来看C语言之变量(3)

观察函数内容,发现这就是一个搬移函数,将数据项从原来的位置搬运到栈段中指定的位置,以供函数调用。076a1085的功能也是类似的。所以从函数传递结构体型的数据是调用搬运函数,用movswmovsb指令将数据项搬运到栈段中供函数调用。因为时间关系,这里不能仔细研究,之后再继续完善。

2、拓展研究

问题:

(1)

从汇编来看C语言之变量

程序1函数f2里076a:0234处的语句jmp 0236指向的是下一条语句,这不是无意义的吗?它起什么作用呢?

答:这里jmp语句是跳转到释放局部变量的结束语句,所以我的猜想如下:1、编译器为了避免程序出错所以要用jmp精确跳转到结束语句。2、编译器给程序预留了一个接口用来存放其他功能的程序。

这里函数返回语句是在函数最后面,如果是选择语句或者有多个返回语句的情况,就会出现这种情况。

(2)函数里局部变量都是第一个定义的在si寄存器里,其他的在栈段里吗?

答:不是,经过实验,只有当该局部变量需要返回时,才存储在si寄存器里,否则只是存储在栈段里。

(3)静态局部变量与全局变量的区别就在于在后者整个程序的所有函数里都能访问,而前者只能在定义的函数里访问吗?

答:最明显的区别就是作用域的区别。

(4)加载第3章的5个程序。查看偏移地址为1fa处的指令,为什么有的程序有“push bp”和“mov bp,sp”两条指令,有的程序没有?

答:我的5个程序都有保护语句,如果没有可能是编译器的问题。

如果用TC2.0编译,是有的,如果用tcc编译,会出现这种情况。

(5)程序1中,全局变量n,是由“unsigned int n”这条语句定义,还是由main函数中的“n=0”这条语句定义?

答:应该是由前者定义的,函数外定义的变量,不管有没有加static,没有初始化的话,系统默认初始化为0。如果在n=0语句之前打印n,是能够打印出它的值的。

(6)结构体中数据项的存储为何不使用push、pop 指令进行操作?

答:题目的意思应该是结构体型数据参数的传递和返回是怎么实现的,我们已知是通过搬运函数来实现的,即将存储结构体函数的数据段的值整体移动到一个栈段中。那么为什么不通过push、pop实现呢?我觉得理由如下:1、c语言是将结构体作为一个数据类型的,和int、char等数据类型一样,所以对它的处理方式和其他数据类型是一样的,即要对它整体来处理,如果用push、pop的话,就要对它里面的数据项分开来处理,这是不符合我们建立结构体数据类型的初衷的。2、如果要对它里面的数据项分开来处理,就要知道它里面有哪些数据项、有几个,那么就需要进行统计,这个是不好实现的(我还没找到实现的方法)。3、我们只需要实现传值的目标而不需要在这个过程中对数据进行处理,那么就要选择最简单快捷、开销最小的方法,很显然块搬运是最好的方式。

(7)程序4中,在声明的局部变量struct stu b的后面,假如在后面定义一个char型变量,所占用的字节数为6(char型数据所占用字节数+局部变量struct stu b的数据项所占字节数);假如在后面定义一个整型变量,所占用字节数8,此时有了1个字节的填充,为什么?

答:

从汇编来看C语言之变量

e是int型,eee是char型,前5个变量所占空间为7个字节,加上eee才8个字节。

从汇编来看C语言之变量

局部变量的情况是一样的,加上int型的e和char型的eee也才8个字节。

如果在结构体数据后面再添加一个独立的int型数据,会出现这种情况。内存对齐的结果,结构体内外都有可能出现。

(8)重新研究,不同类型的变量,存储空间的分配情况。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/a49cf8e75fd06b07f17d557ebc1bbee6.html