1.函数栈桢(stack&frame)
函数调用时栈中分配的内存块。
%fp :帧指针
%sp:栈指针
具体如图:
在IDA中,每个函数前面一部分是这样的:
函数中这样使用%fp和%sp
由上面栈桢的知识可以知道,%fp+arg_xx,等于%fp+一个正数,等于上一层函数的%sp+xxx,所以也就是上一层函数传的参数中%o0-%o5装不下的部分。%fp+var_xx等于%fp-一个正数,这是用来存局部变量的地方。
同理可知,%sp+xxx是给要调用的函数传参数用的,首先传给%o0, %o1……%o5,每个寄存器4字节,如果还有,就继续向%sp+0x5C, %sp+0x60……依次传递。应该注意的是如果传的是double型的参数,应该一个参数占两个寄存器,所以看到的是ldd xxx, %o0, ldd xxx, %o2,%o1,%o3就看不到了。
最后,函数返回值存在%i0中,返回后变成%o0,可以从%o0中获得返回值。例如当返回值为错误代码时,返回后对%o0进行判断,以调用错误处理程序或继续执行。
2.寻址方式
寻址方式是根据指令编码中给出的地址码字段来寻找真实操作数的方式。
(1)立即寻址
操作数是直接通过指令给出,数据就包含在指令的32位编码中
(2)寄存器寻址
寄存器中的数值作为操作数,指令中地址码给出的是寄存器编号
(3)寄存器间接寻址
寄存器用“[ ]”括起来,表示内容,寄存器的值为某个存储器地址,操作数则放在该地址单元中。
(4)基址加偏址寻址
也称为变址寻址,就是将基址寄存的内容与指令中给出的偏移量(偏移地址)相加,形成存储器的有效地址,用于访问基址附近的存储器单元。偏移地址也可以是另一个寄存器。
(5)相对寻址
基地址为程序计数器PC的变址寻址,偏移量指出了目的地址与现行指令之问的相对位置,偏移量与PC提供的基地址相加后得到有效的目的地址。
看起来比较复杂实际上在看汇编代码就很清晰易懂。学过8086寻址方式基本就能看懂SPARC的寻址方式。
3. 分支指令延时间隙
分支语句执行前,紧跟分支指令后面的指令先被执行。
在跳转指令的延时间隙里不方便放有用的指令的情形时,SPARC提供 了“nop”复合指令。nop的执行,它不改变任何寄存器或内存的值。
用加后缀“,a”来声明跳转间隙无效。如果条件分支指令没有发生(不跳转),则跳转间隙中的指令无效(不执行)。
例如:
cmp %g1, 0
bne,a icc, loc_1C354
inc %l1
当判断%g1是否等于0后,根据情况判断是否跳转。如果不等于零则跳转,则跳转前执行inc%l1。如果等于零则不跳转,同时也不执行inc %l1。如果bne后面没有", a"则无论是否跳转都要先执行inc %l1。