程序功能:读引导山区,然后以16进制方式显示在屏幕上。程序可以正确的读引导扇区,显示的结果也都正确,最后调用的一个子过程也正确返回。
问题在于:执行mov ah,4c,再执行int 21指令时,失去响应,无法返回DOS,就连按下Crlt+Alt+Del也不响应。我怀疑唯一的可能是覆盖了dos的某个模块?但是内存完全是dos分配的,我又没干什么非法的勾当。
补充:编译时总提示没有堆栈段,我怕dos看不到我的堆栈段,我设置了1K大小。
代码如下:
DATAS SEGMENT
db 4096 dup(0)
DATAS ENDS
STACKS SEGMENT
DB 1024 DUP(0)
STACKS ENDS
ReadSector PROTO NEAR
MEM_TO_HEX PROTO FAR
.386P
CODES SEGMENT USE16
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV AX,STACKS
MOV SS,AX
MOV SP,1024
PUSH DS
MOV AX,01H ;读取逻辑扇区1
MOV CL,01H ;读取1个扇区长度
CALL ReadSector
MOV AX,512
PUSH AX
PUSH BX
MOV AX,ES ;读取缓冲区段值
MOV DS,AX ;设置为DS,因为DS被MEM_TO_HEX过程默认使用
XOR AX,AX
PUSH AX ;压入显存的偏移地址
MOV AX,0B800H ;ES被MEM_TO_HEX过程默认使用
MOV ES,AX
CALL MEM_TO_HEX
POP DS
MOV AH,4CH
INT 21H
;*********************************************************************
; 软磁盘逻辑扇区编码方式:
;0头0道1扇区~18扇区:对应逻辑扇区号1~18
;1头0道1扇区~18扇区:对应逻辑扇区号19~36
;0头1道1扇区~18扇区:对应逻辑扇区号37~54
;1头1道1扇区~18扇区:对应逻辑扇区号55~72
;
; BIOS中断 int 13H的调用规范
;子中断号 ah=02h 读磁盘 al=要读取的扇区数
; ch=磁道号 cl=起始扇区号
; dh=磁头号 es:bx 缓冲区地址
;*********************************************************************
;---------------------------------------------------------------------
;函数名:
ReadSector PROC NEAR
;入口参数
;ax=逻辑扇区号 cl=要读取的扇区个数 es:bx 缓冲区地址
;---------------------------------------------------------------------
push bp
mov bp,sp
sub sp,2
mov [bp-2],cl
push bx
push ax
mov bl,37
div bl ;商为磁道号
mov ch,al ;填写磁道号
pop ax
mov bl,19
div bl
mov dh,al ;商为磁头号
mov cl,ah ;余数为起始扇区号
mov al,[bp-2] ;填充要读取的扇区数
mov ah,02h ;读扇区
mov dl,00h ;目标存储介质:软磁盘
pop bx
int 13h
add sp,2
pop bp
ret
ReadSector ENDP
;*********************************************************************
; 函数功能:转化指令长度的内存区块为ASCII,转储到目标内存块,目标
; 内存块长度应该是源内存块的4倍,如果内存块的内容均为压
; 缩BCD码,则函数恰好将其转化为ASCII码。
; 入口参数:参数3:目标内存块地址,参数2:源内存块地址,参数1:源
; 内存块大小
; 参数大小:均为2个字节,参数顺序,自右向左
; 注意: 要在16位代码段中使用本函数,子过程已经通过了作者的初步
; 测试,欢迎大家测试并使用。