4

我熟悉 C 编程语言和 z80 汇编,并且我制作了一个简单的 z80“计算机”,它只有 32k ram、32k rom 和 8255 pia 用于 io 控制的 cpu。我已经通过汇编语言子程序让 8255 与我的系统一起点亮 LED。

所以问题是:如果有SDCC(小型设备C编译器)可以将C程序编译成包括z80在内的各种小型CPU的汇编,如果没有stdio库或任何库,你如何创建C程序因为这个系统是多么的定制。我是否被迫先使用程序集,然后将函数作为 ASM 例程进行调用?我是否误解了某种关键思想?我很困惑这是如何工作的。我不能只在没有输出的系统上 printf()。更不用说 printf() 是假设终端以某种方式连接的。

4

2 回答 2

5

您将编写一个特定于平台的 I/O 库,该库利用您的平台可用的任何 I/O 功能。在许多嵌入式系统上,最小标准 I/O 是在 UART 串​​行端口上实现的,因此您的“控制台”可以是主机 PC 上的终端仿真器。

您的 I/O API 不需要像标准库的 stdio 那样复杂。它也不需要用汇编程序编写,内存映射外围设备的寄存器级访问在 C 中是可能的(实际上是正常的) - 毕竟它是一种系统级语言。

尽管如此,SDCC 已经包含一个标准库子集,其中包含一个子集 stdio。所以不清楚你为什么认为你缺乏这种支持。您确实必须提供特定于平台的低级支持,但要支持printf您只需实现putchar()在您选择的标准输出设备上发出一个字符。对于相当微不足道的无缓冲串行输出。更复杂的实现可能使用中断驱动的缓冲串行输出。SDCC 手册中描述了库的移植。

于 2020-11-24T21:10:19.180 回答
1

你说的对。汇编例程包含实际的入口点,在该入口点完成内存初始化,然后该例程调用main().

sdcc/device/lib/z80/crt0.s包含 SDCC 提供的默认启动代码。

如果您的系统需要完成的工作比提供的更多,请参阅 SDCC 手册的第 3.12.3 节,了解如何提供您自己的工作。

至于printf(),你只需要以putchar()某种方式提供。如果它只是out对某些设备的指令,您也可以将其放入其中crt0.s,如下所示:

    .area   _CODE
init:
    call    0x01B0 ; ROM_CLEAR_SCREEN    
    ;; Initialise global variables
    call    gsinit
    call    _main
_exit:
    call    0x0200 ; ROM_GET_KEY
    jr      z, _exit
    call    0x01B0 ; ROM_CLEAR_SCREEN
    ret
_putchar:
    ld      hl, #2
    add     hl, sp
    ld      a, (hl)
    out     (0xBC), a
    ld      hl, #0
    ret
于 2021-02-11T12:22:10.630 回答