我是新手,写了一个简单的程序,但在对文件进行新建以及读写的那一块有点问题,求大家指教
有好几个问题,请大家耐心解答
;描述:
;此程序是模拟一个简单的银行系统,有查询余额,存钱,取钱和退出功能
;金额存储在文件bank.txt中,程序一开始会将bank.txt中的内容读取出来,存在x中(若无此文件,则新建)
;程序结束时,将x中的值写入回bank.txt文件中
;问题:
;1.我用的是emu8086编译器,若我一开始没有在给出的目录里建立bank.txt文件,则会提示无法打开,并没有新建文件
;2.即使我事先在给出的目录里建立了一个bank.txt文件,但是运行完程序后,里面内容并没有改变
;3.我事先在给出的目录里建立了一个bank.txt文件,里面打了一个数字0,调用将x十进制显示的query函数后,为什么还是显示出ASC码48
;4.我在save以及take中都有对输入的数进行判断是否大于9999,但是实际输入的时候我输入大于9999的数,仍然会继续让你输入下去,直到按回车键
;最好能帮我改下程序,达到我想要的功能,或者给我些修改意见
;emu8086编译通过,可以直接运行(如果没有自己建立文件,会提示打开文件失败)
data segment
menu db 'Bank System:',13,10
db '1.query',13,10
db '2.save',13,10
db '3.take',13,10
db '4.exit',13,10
db 'Please choose an order:',13,10,'$'
cr db 13,10,'$'
error db 'error!',13,10,'$'
money db 'money:','$'
number db 'number:',13,10,'$'
x dw 0 ;用来存放从文件中读取出来的字符
path db 'D:\emu8086\MyBuild\bank.txt',00 ;文件的绝对地址
codename db 10 dup(0) ;用来保存文件代号
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
call file_open ;打开文件
call file_read ;将文件内容读取至x中
call file_close ;关闭文件
list:
lea dx,cr
mov ah,9
int 21h
lea dx,menu
mov ah,9
int 21h;显示菜单
mov ah,1
int 21h
cmp al,'1'
jnz a1 ;输入1,调用query,显示x中的数,以十进制显示
call query
jmp list
a1:cmp al,'2'
jnz a2;输入2,调用save,对x中的数据进行操作(加法)
call save
jmp list
a2:cmp al,'3'
jnz a3;输入3,调用take,对x中的数据进行操作(减法)
call take
jmp list
a3:cmp al,'4'
jz e;输入4,调用exit,退出程序
lea dx,error
mov ax,9
int 21h
jmp list
e:call file_open ;打开文件
call file_write ;将x中的数写入到文件中
call file_close ;关闭文件
call exit ;退出程序
query proc;以十进制显示内存x中的数
call cr_lf;回车+换行
lea dx,money;我是新手,这个子程序从网上找的,试了下似乎没有问题,目前没完全理解,所以没有注释
mov ah,9
int 21h
mov ax,x
xor cx,cx
mov bx,10
nx1:
xor dx,dx
div bx
or dx,0e30h
inc cx
push dx
cmp ax,0
jnz nx1
nx2: pop ax
int 10h
loop nx2
ret
query endp
save proc;读取内存x中的数,加上键盘键入的数,再回存至x中
mov ax,0
push ax;初始化ax,并放入堆栈保护起来
save_loop:
call cr_lf;回车+换行
lea dx,number ;显示"number:"
mov ah,9
int 21h
save_in:
mov ah,1
int 21h;输入一个字符
cmp al,13;输入的若是回车,则结束输入
je save_end
cmp al,'0'
jb save_loop ;输入的数小于0,即不是数字,则重新输入
cmp al,'9'
ja save_loop ;输入的数大于9,即不是数字,则重新输入
sub al,30h
mov cl,al;备份键盘键入的新数据
mov ch,0
pop ax
mov dl,10
mul dl;老数据乘以10
add ax,cx;加上新数据
push ax;将ax放入堆栈保护起来,准备下次跳转
cmp ax,9999;如果输入的数大于9999,则重新输入
ja save_loop
jmp save_in;继续输入下一个字符
save_end:
pop ax
mov bx,x
add ax,bx;将输入的数加上x中的数,并回存至x中
mov x,ax
call cr_lf;回车+换行
ret
save endp
take proc;读取内存x中的数,减去键盘键入的数,再回存至x中
mov ax,0
push ax;初始化ax,并放入堆栈保护起来
take_loop:
call cr_lf;回车+换行
lea dx,number;显示"number:"
mov ah,9
int 21h
take_in:
mov ah,1
int 21h;输入一个字符
cmp al,13;输入的若是回车,则结束输入
je take_end
cmp al,'0'
jb take_loop ;输入的数小于0,即不是数字,则重新输入
cmp al,'9'
ja take_loop ;输入的数大于9,即不是数字,则重新输入
sub al,30h
mov cl,al;备份键盘键入的新数据
mov ch,0
pop ax
mov dl,10
mul dl;老数据乘以10
add ax,cx;加上新数据
push ax;将ax放入堆栈保护起来,准备下次跳转
cmp ax,9999;如果输入的数大于9999,则重新输入
ja take_loop
jmp take_in
take_end:
pop ax
mov bx,x
sub bx,ax
mov x,bx;将x减去输入的数,并回存至x中
call cr_lf;回车+换行
ret
take endp
exit proc;退出程序
mov ah,4ch
int 21h
ret
exit endp
cr_lf proc;回车+换行
lea dx,cr
mov ah,9
int 21h
ret
cr_lf endp
file_close proc ;关闭文件
lea si,codename
mov ah,3eh
mov bx,[si]
int 21h
ret
file_close endp
file_open proc;打开文件
lea dx,path
mov ah,3dh
mov al,2;打开文件,进行读/写
int 21h
cmp ax,'02'
jnz a
mov ah,3ch ;如果文件不存在,则新建一个文件
mov cx,00 ;文件属性默认为0
lea dx,path;将绝对地址给bx
int 21h
lea si,codename ;给新建的文件写入初始值0
mov cx,01h
mov bp,0 ;将初始值0放入bp中
lea dx,[bp]
mov ah,40h
lea bx,[si]
int 21h
a: lea bx,codename
mov [bx],ax;将文件代号存至内存codename中
ret
file_open endp
file_read proc;对文件进行读操作
lea si,codename
mov ah,3fh
lea dx,x;读出的数据存到x中
mov cx,02h ;读取两个字节
mov bx,[si];文件代号给bx
int 21h
ret
file_read endp
file_write proc ;对文件进行写操作
lea si,codename
mov cx,02h;写入两个字节
lea dx,x;将x中的数据写入到文件中
mov ah,40h
lea bx,[si];将文件代号给bx
int 21h
ret
file_write endp
code ends
end start
[最优解释]
上调试软件吧,这样简单界面的程序 debug 就可以了。哪个部分有问题就运行到那里,一步步地运行,看哪里和预想的不一样。
另外,内存单元,可以直接访问的,无须再通过寄存器间接地中转,如:
lea si, codename
mov [si], ax
; 可以直接为
mov codename, ax ; codename dw 0 这样定义
[其他解释]
为了这个程序我发了三个求助贴,一步步改进,居然都是你回答的。。。
debug不太会用,只知道单步调试的t命令,程序需要键盘输入的时候就不知道用什么命令了。
汇编的调试比C/C++麻烦多了,对于我这种新手来说非语法错误好难找。
[其他解释]
debug 多用几次也就很简单了,用的多的也就是 u d g p t 等几个命令,间或 a e/f 不过初涉猎者用的机会较小。
非语法错误,调试软件里就是分片执行,看当时的状态是不是和预想的一样,不一样,什么原因,前后看看;一样,问题就在下面一片,继续走。