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