【问题标题】:Stack bounds checking on the Amiga 500Amiga 500 的堆栈边界检查
【发布时间】:2020-05-03 17:10:02
【问题描述】:

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

【问题讨论】:

  • 为什么您的程序“可能会使用大量堆栈空间”?它是某个问题的递归解决方案吗?可以通过迭代解决方案来解决问题吗?或者通过使用公式和简单的算术来避免任何形式的循环?
  • 我在写一个BASIC解释器,表达式解析器是递归的。
  • 据我所知(自从我在 Amiga 上工作几年以来),有一个命令可以启动具有指定堆栈大小的程序。大多数需要更大堆栈的程序在文档中都明确提到了这一点。当然,.info 文件还包含一个堆栈大小字段,如果您想从 Workbench 运行它。也许您可以在文档中简单地提及这一点?并使用一些不同的输入进行测试,以尝试找出堆栈大小的一些常见要求?
  • 查看可用栈的数量,tc_SPUppertc_SPLower的区别是当前运行的进程最后一次切换时可用栈的数量。如果这低于某个数量,比如 1KiB,那么您可以停止您的程序并报告输入太复杂,并且您的程序需要重新运行并增加堆栈(可能显示要运行的示例命令)。
  • 谢谢。那将是堆栈命令。我的问题是解释器所需的堆栈数量取决于最复杂的表达式。例如,a*(b+c) 比 a*d 需要(稍微)更多的堆栈空间。我宁愿显示错误消息而不是崩溃。另外,我真的很想了解堆栈是如何工作的,以防我将来需要它用于其他项目。

标签: amiga


【解决方案1】:

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

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

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

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

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

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

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

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

AmigaDOS 将一个合适的返回地址压入堆栈,告诉 CLI 重新获得控制权并卸载您的程序。下面这个关于 stack at 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 内核参考手册:库和设备,第 584 页:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2010-12-04
    • 1970-01-01
    • 2019-07-24
    • 1970-01-01
    • 2011-01-09
    相关资源
    最近更新 更多