Gdb SPARC和HP-UX中的叶函数

Gdb SPARC和HP-UX中的叶函数,gdb,disassembly,sparc,hp-ux,Gdb,Disassembly,Sparc,Hp Ux,我刚刚读了一篇Phrack文章,文章中有HP-UX中的反汇编功能。我了解到在HP-UX和SPARC下有两类功能;叶函数和非叶函数。以下是我从中提取的拆解部分 (gdb)禁用叶 函数foo的汇编程序代码转储: 0x3280:复制r3,r1 0x3284:复制sp,r3 0x3288:stw,ma r1,40(sr0,sp) 0x328c:stw r26,-24(sr0,r3) 0x3290:stw r0,8(sr0,r3) 0x3294:ldi 1,r19 0x3298:stw r19,8(sr0

我刚刚读了一篇Phrack文章,文章中有HP-UX中的反汇编功能。我了解到在HP-UX和SPARC下有两类功能;叶函数和非叶函数。以下是我从中提取的拆解部分

(gdb)禁用叶
函数foo的汇编程序代码转储:
0x3280:复制r3,r1
0x3284:复制sp,r3
0x3288:stw,ma r1,40(sr0,sp)
0x328c:stw r26,-24(sr0,r3)
0x3290:stw r0,8(sr0,r3)
0x3294:ldi 1,r19
0x3298:stw r19,8(sr0,r3)
0x329c:ldo 40(r3),sp
0x32a0:ldw,mb-40(sr0,sp),r3
0x32a4:bv,n r0(rp)
汇编程序转储结束。
(gdb)
通常在调用函数时,返回地址被推送到堆栈上,以便在函数完成执行后,程序知道将控件返回到何处。对于这些叶函数,这是如何工作的

我没有任何HP-UX/SPARC机器的访问权限,因此我没有办法自己尝试(由于同样的原因,我也不太了解这种情况下的组件)


有人能解释一下在这种情况下控件是如何返回给被调用函数的吗?

首先,您链接到的文档和显示的代码不是Sparc,而是PA-RISC,这是一种独特的体系结构。据我所知,目前还没有在基于Sparc的系统上运行的HP/UX版本

然而,关于叶函数的观点在许多体系结构中是相似的,包括Sparc、PA-RISC、PowerPC、ARM、MIPS。。。事实上,所有的RISC架构。对于所有这些,执行函数调用的操作码不在堆栈上存储返回地址;事实上,硬件不存在已知的“真实”堆栈。相反,使用特定寄存器作为堆栈指针只有一个软件约定。调用操作码将返回的地址存储在特定寄存器中,通常称为“链接寄存器”。从函数返回的操作码只是读取该寄存器

如果函数本身(我们称之为A)调用另一个函数(B),那么该嵌套调用也将使用链接寄存器;但是,在返回时,将需要链接寄存器的内容。因此,必须将链接寄存器保存在某个位置,通常保存在内存中,更准确地说,保存在通常用作“堆栈”的内存区域中

叶函数是不调用其他函数的函数;它只是完成了它的工作,然后返回。叶函数不需要将链接寄存器保存在堆栈上,因为任何内容都不会改变链接寄存器的内容

另一个也是常规的约束是关于堆栈帧结构。某些体系结构上的某些操作系统坚持以非常特定的方式(称为“堆栈帧”)使用堆栈的函数,调试器可以可靠地对此进行探索。然后,该规范调用将返回地址保存在堆栈上的一个精确插槽中,被调用函数必须在执行的很早就这样做。然后,相同的操作系统可能会声明这不是叶函数绝对需要的(如果一个无帧函数不调用其他函数,则调试器更容易处理该函数,即堆栈上没有被推到缺少的帧之上的帧)。不设置堆栈帧比设置堆栈帧更有效(在执行速度和代码大小方面),因此出现异常

(gdb) disass leaf
Dump of assembler code for function foo:
0x3280 <leaf>:           copy r3,r1
0x3284 <leaf+4>:         copy sp,r3
0x3288 <leaf+8>:         stw,ma r1,40(sr0,sp)
0x328c <leaf+12>:        stw r26,-24(sr0,r3)
0x3290 <leaf+16>:        stw  r0,8(sr0,r3)
0x3294 <leaf+20>:        ldi 1,r19
0x3298 <leaf+24>:        stw  r19,8(sr0,r3)
0x329c <leaf+28>:        ldo 40(r3),sp
0x32a0 <leaf+32>:        ldw,mb -40(sr0,sp),r3
0x32a4 <leaf+36>:        bv,n r0(rp)
End of assembler dump.
(gdb)