2

我在 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 可能在堆栈上的一些其他数据?

4

1 回答 1

2

在重新(……)阅读手册之后,我可能已经明白了。

来自Amiga ROM 内核参考手册:库和设备,第 584 页:

CLI 不会为程序创建新进程;它跳转到程序的代码,程序与 CLI 共享进程。

由此,我推测 FindTask(NULL) 返回的进程是 CLI 进程,而 tc_SPUpper 和 tc_SPLower 指的是该进程的堆栈。

来自AmigaDOS 开发者手册,p. 160:

当 CLI 启动一个程序时,它会为该程序分配一个堆栈。此堆栈最初为 4000 字节,但您可以使用 STACK 命令更改堆栈大小。AmigaDOS 在您运行程序之前从一般空闲内存堆中获取此堆栈;但是,它与 CLI 使用的堆栈不同。

由此,我得出结论,我的程序堆栈与 FindTask(NULL) 返回的任务中的堆栈是分开的。

也来自AmigaDOS 开发者手册,第 1 页。160:

AmigaDOS 将一个合适的返回地址压入堆栈,告诉 CLI 重新获得控制权并卸载您的程序。在 4(SP) 的堆栈上低于此值的是堆栈的大小(以字节为单位)......</p>

由此,我得出结论,对于从 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 内核参考手册:库和设备,第 584 页:

当用户激活工具或项目时,Workbench 会运行程序。该程序是一个单独的进程,并且与 Workbench 异步运行。

我已经确认这两个值之间的差异确实是 .info 文件中指定的堆栈大小。

于 2020-05-04T20:14:38.377 回答