今天我在做汇编实验的课程设计,需要调用BIOS的10h中断中的13h功能实现字符串的打印
但是在反复的调用中,我的字符串打印都不能成功的调用,但是用DOS打印字符串是可以成功打印的,所以我被卡了很长时间在这个问题之上。
后来我以为是使用了宏定义的问题,然后我使用了子程序来进行打印,经过了比较复杂的堆栈传参后发现,还是失败了。
后来我怀疑是字符串地址的问题,但是这DOS都已经是打印正确的了,说明地址传参是没有问题的了
然后我使用了同学可以跑通的代码,copy到我的代码中,发现还是没有成功打印。但是同学的代码我是可以成功的跑出来的.
这个时候其实我一直都是用排BUG比较常用的方法——控制变量。
每一次都只改变一个条件,然后测试每一次的结果有没有正确。当然这里没有成功
然后我就重新新开了一个文件,然后从头开始写这个代码——就是开始进行消融(类似于消融这种思想)
我先是直接调用寄存器,不使用子程序,不使用宏定义——打印成功了!
现在我们就可以知道,只要我们一直添加相关的条件,然后不断的进行实验,就可以知道为什么在原代码中不可以打印成功
1.使用宏定义——成功
2.使用equ来表示各种变量——成功
。。。。。。。
最后其实我就发现,两个代码在这个模块上,就是我的原代码会套在MAIN Pro 函数中的
我就想是不是这个问题,因为我之前没有多用过这个函数的功能
结果我加上了MAIN函数就发现了,出现了和原函数一样的问题!
所以现在问题就迎刃而解了,不要在MAIN pro中调用BIOS 10h中断的13h打印字符串的功能,把宏定义放在上面,然后把子程序放在下面,我们不用main 规定程序的开始位置
至于具体是什么原因还不得而知,但是这样解决问题的思想是很重要的
因为在原函数中有太多的参数和变量参数,可能不能很好的把BUG排出来,我们可以设计一个消融实验,一步一步添加条件,从而逼近原来的实验环境,从而达到实验目的。
; multi-segment executable file template.
data segment
; add your data here!
pkey db "press any key...$"
ESC_KEY EQU 1BH
WIN_ULC EQU 30
WIN_ULR EQU 8
WIN_LRC EQU 50
WIN_LRR EQU 16
WIN_WIDTH EQU 20
blackLRed equ 00001100b
blackGreen equ 00000010b
blackYellow equ 00001110b
blackblued equ 00000001b
blackWhite equ 00001111b
blueLRed equ 00011100b
blueRed equ 00000100b
blueWhite equ 00011111b
redWhite equ 01001111b
MSGWELCOME db "____Welcome to typewriting game!$"
lenWELCOME equ $-MSGWELCOME
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
; add your code here
setprint macro choice
push ax
mov ah,0h
mov al,choice
int 10h
pop ax
endm
printString macro addr,attr,length,start_row,start_col,page,guangbiao
push ax
push bx
push cx
push dx
push bp
mov ah,13h
;lea bp,addr
mov bx,offset addr
;mov bp,offset addr ;字符串地址
mov bp,bx
;mov bp,addr
mov bl,attr
mov cx,length
mov dh,start_row
mov dl,start_col
mov bh,page
mov al,guangbiao ;光标的移动方式
int 10h
pop bp
pop dx
pop cx
pop bx
pop ax
endm
;MAIN proc
setprint 02h
printString msgwelcome,bluewhite,lenwelcome,1,1,0,0
lea dx, pkey
mov ah, 9
int 21h ; output string at ds:dx
;main endp
;end main
; wait for any key....
mov ah, 1
int 21h
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler.