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



我对汇编语言有些陌生,想了解它是如何在旧系统上工作的。我知道大内存模型使用远指针,而小内存模型使用近指针,并且大模型中的返回地址是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子例程上标记这个假设,所以没有将正确的值推到堆栈上/从堆栈中弹出的代码被组装起来。

最新更新