我的Commodore Amiga 500上运行了一个68000汇编语言程序,该程序可能会占用大量堆栈空间,所以我想进行边界检查。
如果我调用FindTask(NULL(,并检查tc_SPUpper和tc_SPLower,我会得到$c22c24和$c21fa4,这是3200字节的堆栈;但是,CLI分配了8000个字节的堆栈,程序以一个$c29598的堆栈指针开始,该指针的内存比tc_SPUpper高出约26K。
我在AmigaDOS开发人员手册中读到,在开始时,4(sp(包含堆栈大小。此值包含8000。("在4(SP(的堆栈上,低于此值的是以字节为单位的堆栈大小,如果您希望执行堆栈检查,这可能会很有用。"(
我可以安全地将sp-4(sp(作为堆栈的下限吗?我是否需要考虑堆栈大小、返回地址以及CLI在堆栈上可能包含的其他一些数据?
在重新阅读(…(手册后,我可能已经明白了。
来自Amiga ROM内核参考手册:Libraries&设备,第584页:
CLI不会为程序创建新进程;它跳到程序的代码,程序与CLI共享进程。
由此,我推断FindTask返回的进程(NULL(是CLI进程,而tc_SPUpper和tc_SPLower指的是该进程的堆栈。
来自AmigaDOS开发人员手册,第160页:
CLI启动程序时,会为该程序分配堆栈程序此堆栈最初为4000字节,但您可以更改堆栈大小。AmigaDOS从在运行程序之前的一般空闲内存堆;是的但是,与CLI使用的堆栈不同。
由此,我得出结论,我的程序堆栈与FindTask(NULL(返回的任务中的堆栈是分离的。
同样来自AmigaDOS开发者手册,第160页:
AmigaDOS将一个合适的返回地址推送到堆栈上,告诉CLI重新获得控制并卸载程序。下面是堆栈4(SP(是以字节为单位的堆栈大小…
由此,我得出结论,对于从CLI运行的程序,以下代码将为我提供堆栈上可用的最低地址。
move.l sp,d0 ; current stack pointer
addq.l #8,d0 ; return address and stack size
sub.l 4(sp),d0 ; size of stack
move.l d0,stack_lowest ; save for stack checking
对于从Workbench启动的程序,我认为tc_SPUpper和tc_SPLower是我想要的值。
来自Amiga ROM内核参考手册:Libraries&设备,第584页:
当用户激活一个工具或项目时,Workbench会运行一个程序。此程序是一个独立的进程,异步运行到工作台。
我已经确认,这两个值之间的差异实际上是.info文件中指定的堆栈大小。