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

在自加1运算时,整型是inc word ptr,对1个字的数据进行操作;字符型是inc byte ptr,对1个字节的数据进行操作;长整型是先对低四位数据进行运算,再用位运算符adc对高四位进行运算得到结果。

下面来看程序4:

从汇编来看C语言之变量

观察main函数的内容:

从汇编来看C语言之变量

从汇编来看C语言之变量

从汇编来看C语言之变量

从汇编来看C语言之变量

我们注意对变量a、b各个数据项的赋值部分:a的每个数据项都有固定的内存地址,而b的数据项都是存储在栈段里面,因为a是全局变量而b是局部变量。而且a、b里面的数据项的各自的存储空间是相邻的。

观察发现,在赋值语句后,程序还有一大段的指令,这些指令是用来执行printf函数的功能的。

下面来看程序5:

从汇编来看C语言之变量

main函数的内容有:

从汇编来看C语言之变量

从汇编来看C语言之变量

从汇编来看C语言之变量

观察发现程序中出现了lea指令,查询可知lea指令的作用是取偏移地址。程序里面出现了很多call指令,经过实验,发现调用f函数的是call 0256,调用func函数的是call 0266.main函数是怎么把结构体数据a传给函数f的呢?我们先看看f中调用的结构体数据在什么地方:

从汇编来看C语言之变量

调用的数据在栈段里面,a.a是bp+4,a.b是bp+6,a.c是bp+8.

那么main函数传值应该是将数据项压栈的过程。

但我们发现在main函数里从语句call 0266到call 0256之间没有压栈的语句,只是调用了两个函数:call 076a:1085和call 076a:10a1,这两个函数肯定是对结构体数据和栈进行处理的,但是我发现难以看懂看懂它们的内容。那么不如换一种思路,我们先看看func()返回的内容放在什么地方,下面是函数func的内容:

从汇编来看C语言之变量

从汇编来看C语言之变量

我们发现func在对数据项进行赋值后,同样调用了076a:1085处的函数,而与main函数中比较,main函数是将ds、ax寄存器压栈,而这里是将ss、bx寄存器压栈,即将数据项的段地址和第一项的偏移地址压栈,再调用076a:1085进行处理。但是这个函数具体有什么作用呢?我还无法得出结论。在网上找到下面一段话:

语言中函数返回结构体时如果结构体较大则在调用函数中产生该结构的临时变量,并将该变量首地址传递给被调用函数,被调用函数返回时根据该地址修改此临时变量的内容,之后在调用函数中再将该变量复制给用户定义的变量,这也正是 语言中所谓值传递的工作方式。
    如果结构体较小则函数返回时所用的临时变量可保存在寄存器中,返回后将寄存器的值复制给用户定义的变量即可。

我对这段话的理解是,函数076a1085创建了一个临时变量,将局部变量的结构体对象a的各项数据复制到这个临时变量里,之后函数func结束,func里的变量a从栈中被释放,之后main函数再调用076a:10a1,将这个临时变量的值压栈传给函数f使用。

再来看看076a:10a1的内容:

从汇编来看C语言之变量

从汇编来看C语言之变量

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

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