如何将针对小内存模型的 DOS 程序集转换为大内存模型?

How do I translate DOS assembly targeted for the small memory model to the large memory model?

我对汇编语言有些陌生,想了解它在旧系统上的工作原理。我了解到大内存模型使用远指针而小内存模型使用近指针,并且大模型中的 return 地址是 4 个字节而不是两个,所以第一个参数从 [bp+4][bp+6]。然而,在将图形库从小模型适配到大模型的过程中,还有一些其他的细微之处我似乎不太理解。 运行 这段来自 C 的带有大内存模型的代码本应清屏,但它挂起了系统(它是用 TASM 组装的):

; void gr256cls( int color , int page );

COLOR   equ [bp+6]
GPAGE   equ [bp+8]

    .MODEL LARGE,C
.186
    public C    gr256cls
    .code
gr256cls    PROC
    push    bp
    mov bp,sp
    push    di
    pushf
    jmp skip_1
.386
    mov ax,0A800h
    mov es,ax
    mov ax,0E000h
    mov fs,ax
    CLD
    mov al,es:[bp+6]
    mov ah,al
    mov bx,ax
    shl eax,16
    mov ax,bx

    cmp word ptr GPAGE,0
    je  short cls0
    cmp word ptr GPAGE,2
    je  short cls0
    jmp short skip_0
cls0:
    mov bh,0
    mov bl,1
    call    grph_cls256
skip_0:
    cmp word ptr GPAGE,1
    je  short cls1
    cmp word ptr GPAGE,2
    je  short cls1
    jmp short skip_1
cls1:
    mov bh,8
    mov bl,9
    call    grph_cls256
skip_1:
.186
    popf
    pop di
    pop bp
    ret
.386
grph_cls256:
    mov fs:[0004h],bh
    mov fs:[0006h],bl
    mov cx,16384
    mov di,0
    rep stosd
    add word ptr fs:[0004h],2
    add word ptr fs:[0006h],2
    mov cx,16384
    mov di,0
    rep stosd
    add word ptr fs:[0004h],2
    add word ptr fs:[0006h],2
    mov cx,16384
    mov di,0
    rep stosd
    add word ptr fs:[0004h],2
    add word ptr fs:[0006h],2
    mov cx,14848    ;=8192+6656
    mov di,0
    rep stosd
    ;; Freezes here.
    ret
gr256cls    ENDP
    end

挂在grph_256cls末尾的ret处。事实上,即使我从函数的开头立即 ret 它仍然会立即挂起。在两种模式下编写汇编代码时是否有完整的差异列表,以便我更容易理解发生了什么?

编辑:澄清一下,这是原始来源。这不是生成的输出;它旨在被组装并链接到一个库中。

我将 grph_256cls 更改为带有 PROC FAR 的过程,现在它可以正常工作了:

grph_cls256 PROC FAR
  ...
grph_cls256 ENDP

这个问题与 C 期望根据内存模型调用函数的方式有关。在大内存模型中,所有的函数调用都是far。在尝试 call 时,我没有在 grph_256cls 子例程上标记这个假设,所以没有 push/pop 正确值的代码 onto/off 堆栈被组装起来。