美好的一天!我听到了一个代码片段,它使用视频模式10h
打印欢迎消息(菜单)。按下4
时,它应从文件中读取并在屏幕上显示其内容。但是,它显示垃圾值,我必须打开DosBox并重新安装。
.model small
.stack 1024
.data
MENU DB 10,""
DB 10," Welcome " ;24
DB 10,""
DB 10,"1 Novice" ;3, 9
DB 10,"2 Boss" ;3, 6
DB 10,"3 Superb" ;3, 11
DB 10,"4 Scores"
DB 10,""
DB 10,"Choice: ","$" ;8
ROW1 DB 5
ROW2 DB 10
COL DB 25
Choice DB ?
; OTHER DECLARATIONS FOR COLORING I WON'T SHOW FOR SIMPLICITY
FileName DB "file.txt",0,8 ; name of file to open
Handle DW ? ; to store file handle
BufferSeg dw 0
ErrMsgOpen db "Error opening `"
FileLength dw 0
nextLine db 13,10
.code
DisplayFile PROC NEAR
;escape to video mode
mov ax,0A000h
mov es,ax
xor di,di
xor ax,ax
mov cx,32000d
cld
rep stosw
mov ax,cs
mov ds,ax
mov bx,ss
add bx,200h/10h ;get past the end of the file
mov [BufferSeg],bx ;store the buffer segment
;call WriteFile
push ds
mov ax,cs
mov ds,ax
mov ax,3d00h ;open file (ah=3dh)
mov dx,offset FileName
int 21h
mov bx,ax ;move the file handle into bx
mov ds,[BufferSeg]
mov dx,0 ;load to [BufferSeg]:0000
mov ah,3fh
mov cx,0FFFFh ;try to read an entire segments worth
int 21h
mov [cs:FileLength],ax
mov ah,3eh
int 21h ;close the file
cld
mov si,0
mov cx,[cs:FileLength]
PrintLoop:
mov ah,2
lodsb
mov dl,al
int 21h ;print a character
dec cx
jne PrintLoop
pop ds
ret
OpenError:
mov ah,9
mov dx,offset ErrMsgOpen
int 21h
pop ds
ret
DisplayFile ENDP
.STARTUP
mov ax, @data
mov ds, ax
@welcome:
mov ax, 3
int 10h
MOV AX, 3 ; 80x25 color
INT 10H ; video BIOS call
MOV AH, 2 ; set cursor position
MOV BH, 0 ; display page number
MOV DH, ROW1 ; row number
MOV DL, COL ; column number
INT 10H ; video BIOS call
LEA BP, ATT_BRICK ; point to first attribute array
CALL FAR PTR STICK ; display first line of video text
;scanf user's choice
mov ah, 01h
int 21h
sub al, '0'
mov Choice, al
; OTHER CODES
cmp al, 4
je @scores
@score:
call DisplayFile
@quit:
mov ax, 4c00h ;call dos to exit
int 21h
.EXIT
END
基本上它是将结果保存在文件中的游戏。我可以正确地写入文件,但是当我尝试从中读取时,它不会在屏幕上输出。请帮我。非常感谢你!
修改
这与DisplayScore proc near
所做的相同,但是在一个单独的asm文件中(只是为了测试从文件读取是否有效)。
.MODEL SMALL
.STACK 200h
.CODE
Ideal
;===- Data -===
BufferSeg dw 0
ErrMsgOpen db "Error opening `"
FileName db "file.txt",0,8,"'$" ;8 is a delete character
;0 is required for filename
;(displays a space)
FileLength dw 0
buffer db "hehe$"
;===- Subroutines -===
PROC DisplayFile NEAR
push ds
mov ax,cs
mov ds,ax
mov ax,3d00h ;open file (ah=3dh)
mov dx,offset FileName
int 21h
jc OpenError
mov bx,ax ;move the file handle into bx
mov ds,[BufferSeg]
mov dx,0 ;load to [BufferSeg]:0000
mov ah,3fh
mov cx,0FFFFh ;try to read an entire segments worth
int 21h
mov [cs:FileLength],ax
mov ah,3eh
int 21h ;close the file
cld
mov si,0
mov cx,[cs:FileLength]
PrintLoop:
mov ah,2
lodsb
mov dl,al
int 21h ;print a character
dec cx
jne PrintLoop
pop ds
ret
OpenError:
mov ah,9
mov dx,offset ErrMsgOpen
int 21h
pop ds
ret
ENDP DisplayFile
;===- Main Program -===
START:
mov ax,cs
mov ds,ax
mov bx,ss
add bx,200h/10h ;get past the end of the file
mov [BufferSeg],bx ;store the buffer segment
;call WriteFile
call DisplayFile
mov ax,4c00h
int 21h
END START
答案 0 :(得分:0)
如果我们启动我们的应用程序,那么我们将成为DOS中的所有免费ram,因此我们无法知道我们实际可以使用多少ram以及为DOS和TSR-Drivers保存哪些段地址。因此我们必须向DOS回馈我们此时尚未需要的所有ram,之后我们可以从DOS开始请求一个新指定的公羊,从一个持续拥有免费ram的段地址开始,这些ramnts不是DOS或驱动程序使用的
call SETFREE ; calculate the amoung of ram that we need
; for running our application and giviving
; back the rest of ram to DOS
mov bx, 2000h ; request/reserv 128 KB ram from DOS
call GETSPACE
jc NOSPACE ; Error!
mov [NEWSEG], ax ; save segment address
;------------------------------------
SETFREE: mov bx, ss ; First we subtract both segmentaddresses
mov ax, es ; for to become the amoung of paragraphs
sub bx, ax ; from the PSP to the beginning of the stack.
mov ax, sp ; Because our stackpointer beginn at the end
add ax, 0Fh ; of the stacksegment, we can use the stackpointer
shr ax, 4 ; for the length of the stack.
add bx, ax
mov ah, 4Ah ; Set new size
int 21h
ret
;------------------------------------
GETSPACE: mov ah, 48h ; BX = number/16
int 21h
ret