我对汇编语言有些新意,并希望了解它在旧系统上的工作原理。我知道大内存模型使用远指针,而小内存模型使用近指针,并且大型模型中的返回地址是4个字节而不是2个,因此第一个参数从[bp+4]
更改为{{1 }}。但是,在从小型到大型模型中调整图形库的过程中,还有其他一些我似乎无法理解的细微之处。使用C中的大内存模型运行此代码应该清除屏幕,而是挂起系统(它是用TASM组装的):
[bp+6]
它挂在; 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
末尾的ret
处。事实上,即使我从函数的开头立即grph_256cls
它仍然挂起。在两种模式下编码汇编时是否有完整的差异列表,所以我可以更容易地理解发生了什么?
编辑:为了澄清,这是原始来源。这不是生成的输出;它旨在组装并链接到一个库中。
答案 0 :(得分:1)
我将grph_256cls
更改为PROC FAR
的程序,现在可以正常运行:
grph_cls256 PROC FAR
...
grph_cls256 ENDP
问题与C期望如何根据内存模型调用函数有关。在大内存模型中,所有函数调用都是far
。在尝试使用grph_256cls
时,我没有在call
子例程上标记这个假设,因此代之以不会将正确值推入/弹出堆栈的代码组装起来。