在自加1运算时,整型是inc word ptr,对1个字的数据进行操作;字符型是inc byte ptr,对1个字节的数据进行操作;长整型是先对低四位数据进行运算,再用位运算符adc对高四位进行运算得到结果。
下面来看程序4:
观察main函数的内容:
我们注意对变量a、b各个数据项的赋值部分:a的每个数据项都有固定的内存地址,而b的数据项都是存储在栈段里面,因为a是全局变量而b是局部变量。而且a、b里面的数据项的各自的存储空间是相邻的。
观察发现,在赋值语句后,程序还有一大段的指令,这些指令是用来执行printf函数的功能的。
下面来看程序5:
main函数的内容有:
观察发现程序中出现了lea指令,查询可知lea指令的作用是取偏移地址。程序里面出现了很多call指令,经过实验,发现调用f函数的是call 0256,调用func函数的是call 0266.main函数是怎么把结构体数据a传给函数f的呢?我们先看看f中调用的结构体数据在什么地方:
调用的数据在栈段里面,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的内容:
我们发现func在对数据项进行赋值后,同样调用了076a:1085处的函数,而与main函数中比较,main函数是将ds、ax寄存器压栈,而这里是将ss、bx寄存器压栈,即将数据项的段地址和第一项的偏移地址压栈,再调用076a:1085进行处理。但是这个函数具体有什么作用呢?我还无法得出结论。在网上找到下面一段话:
C 语言中函数返回结构体时如果结构体较大, 则在调用函数中产生该结构的临时变量,并将该变量首地址传递给被调用函数,被调用函数返回时根据该地址修改此临时变量的内容,之后在调用函数中再将该变量复制给用户定义的变量,这也正是 C 语言中所谓值传递的工作方式。
如果结构体较小, 则函数返回时所用的临时变量可保存在寄存器中,返回后将寄存器的值复制给用户定义的变量即可。
我对这段话的理解是,函数076a:1085创建了一个临时变量,将局部变量的结构体对象a的各项数据复制到这个临时变量里,之后函数func结束,func里的变量a从栈中被释放,之后main函数再调用076a:10a1,将这个临时变量的值压栈传给函数f使用。
再来看看076a:10a1的内容: