查看贴子 返回上一页


贴子作者:yuanmh 发贴日期:2001-11-12 17:59
阅读次数:2116 回复条数:23
所属版块:计算机与网络 最后回复日期:2001-11-25 14:04
 
标题:关于8086汇编语言
内容:  
谁知道如何从键盘输入,屏幕输出整型数,而不是用DOS调用输入、输出ASCII码。

回复:

贴子作者:lifanxi 发贴日期:2001-11-12 22:22
不用DOS调用可以用BIOS调用,输入是字符的ASCII,然后自己把它变成整型。
输入123,就等于输入了1*10*10+2*10+3。
贴子作者:lifanxi 发贴日期:2001-11-13 00:01

写了一段小程序,看看吧。写得比较垃圾——懒得费脑子。
实现了输入数字(最多10位),并把它变成整型数,只用了BIOS的10H中断。没用DOS中断.
不过现在有很多很多问题,比如:输入非数字就出错了!输入Backspace不管用了,所有功能键都失灵了。———自己慢慢完善吧,我抛砖引玉。
不过我觉得真是不必要如此,难到真的要写一个不在DOS/Windows下运行的程序?(写新的操作系统????!UNIX下用汇编?)
如果可以用DOS中断,可以用21H的0A功能,输入一个字符串,然后对字符串分析,判断是不是有非法字符,如果没有,可以把它转成数字型的,转换的方法就是依次读出每一个字符,然后把临时变量乘10,加上新的字符ASCII码减30H(见下面的程序一), 比用BIOS中断简单的多。
至于数字的输入,只是做上述操作的反向工作,给你看一个例子(程序二)可以输出整数123。
有不明白的我们再讨论吧!

程序一
d_seg segment
    string db 10 dup(0) ;存放输入的字符串
    strlen dw ?   ;存放输入的字符串的长度
    result dw ?   ;存放最终处理好的整型数
d_seg ends
c_seg segment para
 assume cs:c_seg,ds:d_seg
start:
    mov ax,d_seg
    mov ds,ax
;输入字符串,回车结束
    mov si,0 
    mov result,0
again: mov ah,0
    int 16h
    cmp al,13
    jz calc
    mov string[si],al
    mov bl,0
    mov ah,0eh
    int 10h
    inc si
    cmp si,10
    jnz again
;计算字符串的值,并存到result单元,不输出,要测试这个程序的有效性可以用DEBUG或Turbo Debug等软件.
;如果要输出可以直接把string单元的东东输入,也可以把result重新转成字符再输出(多此一举?).
calc: mov strlen,si
    mov si,0
again1:mov al,10
    mul result
    mov bl,string[si]
    mov bh,0
    sub bx,30h;数字的ASCII码减30H正好等于该数字.
    add ax,bx
    mov result,ax
    inc si
    cmp si,strlen
    jnz again1

    mov ah,4ch   ;Program end,exit.
    int 21h
c_seg ends
 end start

程序二:
c_seg segment para
 assume cs:c_seg
start:
    mov bx,123   ;这里的123可以是任何3位整数,如果要实现大于3位数,就要修改下面的程序,加几段就可以了。

    mov ax,bx
    mov cl,100
    div cl
    or al,30h
    mov dl,al
    mov bl,ah
    mov ah,02h
    int 21h     ;Output 1

    mov al,bl
    mov ah,0
    mov cl,10
    div cl
    or al,30h
    mov dl,al
    mov bl,ah
    mov ah,02h
    int 21h     ;Output 12

    mov dl,bl  
    or dl,30h
    int 21h     ;Output 123

    mov ah,4ch   ;Program end,exit.
    int 21h
c_seg ends
 end start
贴子作者:yuanmh 发贴日期:2001-11-13 12:57
lifanxi:
其实我问的是如何不通过ascii输入输出整数(小数就更好了)。譬如直接将某个寄存器的值以十进制输出,象高级语言一样。一位一位搞太麻烦了。
有道作业题,12月才交,老师好象还没在他的主业上发出来,是设计一个存取款器,如象上面的方法编太长了,干脆到时候帮我编一下吧。
贴子作者:yuanmh 发贴日期:2001-11-13 13:03
已经发出来了,在sung1615.home.sohu.com.
感激不尽。
是用masm汇编的。
贴子作者:lifanxi 发贴日期:2001-11-13 21:13
你们那个破老师的主页好像打不开呀!
贴子作者:yuanmh 发贴日期:2001-11-15 09:23
题目如下,花不了你多少时间的。
程序设计题:
用8086汇编语言设计一存取款小软件系统。要求进入系统后,屏幕上显示"欢迎使用本系统",另起行显示"输入密码:"。允许三次输入错误密码后可重新输入密码,三次输入都出错则返回DOS。密码输入正确即进入本人帐号,并在屏幕上显示:
"1 返回DOS 2 查阅余额 3 存款 4 取款"
然后按1,2,3,4键选择所需工作方式。
以上各方式有如下功能:
1 返回DOS-- 退出小系统,返回DOS
2 查阅余额-- 显示本人帐号内余额(元)
3 存款-- 输入存款数目,即与余额相加
4 取款-- 输入取款数目,即与余额相减
按2,3,4键即进入相应方式,以ENTER键结束,结束后再显示:
"1 返回DOS 2 查阅余额 3 存款 4 取款"
以上设计要求在2001年12月内完成,作为考核内容。
说明: ①屏幕显示可用英文,②帐号内要求可存额不小于十进制6位数
贴子作者:lifanxi 发贴日期:2001-11-15 22:47
好像比较难,我们学汇编的时候没这么高的要求.
等一段时间吧,最近没空帮你研究这个.
贴子作者:yuanmh 发贴日期:2001-11-16 16:03
那就只能我自己干了。有没有好的编辑,汇编,调试程序推荐一个,我现在用的烂透了,要先推出编辑程序,再汇编,出了错还要再回去,烦死人。
贴子作者:虫虫 发贴日期:2001-11-17 10:27
写的不错,站长同志,到时候毕业设计有关程序方面还请多帮帮忙!
贴子作者:陈志强 发贴日期:2001-11-17 11:26
说实话,我现在只会读汇编语言,如果让我编,这种难度好象还是有点问题的。上个学期的考试我最后2个题目只做了个看程序的,编程序的连个字也没有写!!
贴子作者:yuanmh 发贴日期:2001-11-17 22:18
今天奋战近12小时,终于把程序完成了。
眼睛都花了
只见到QQ上人来人往,却惟独没有空白,奇怪啊

贴子作者:yuanmh 发贴日期:2001-11-17 22:25
DATA SEGMENT
BUF1 DB ''Welcome to use this system.'',0DH,0AH,''$''
BUF2 DB ''Please input your password.'',0DH,0AH,''$''
BUF3 DB ''1. Back to DOS  2. Look up  3. Store money  4. Draw money'',0DH,0AH,''$''
BUF4 DB ''store money successfully.'',0DH,0AH,''$''
BUF5 DB ''draw money successfully.'',0DH,0AH,''$''
BUF6 DB '' yuan'',0DH,0AH,''$''
PASSWORD DB ''123456''
IN_WORD DB 7
  DB ?
THE_IN_WORD DB 7 DUP(?)
INPUT_MONEY DB 11
 DB ?
 DB 11 DUP(?)
 DB 0DH,0AH,''$''
ACCOUNT DB 00H
    DB 00H
  DB 00H
  DB 00H
  DB 00H
  DB 00H
  DB 00H
  DB 00H
  DB 00H
  DB 00H
  DATA ENDS
STACK SEGMENT STACK ''STACK''
DW 50 DUP(?)
TOP LABEL WORD
CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX,DATA
   MOV DS,AX
MOV ES,AX
MOV AX,STACK
MOV SS,AX
MOV SP,OFFSET TOP
MOV DX,OFFSET BUF1
MOV AH,9
INT 21H
MOV BX,3
INPUT:
MOV DX,OFFSET BUF2
MOV AH,9
INT 21H
MOV DX,OFFSET IN_WORD
MOV AH,0AH
INT 21H
LEA SI,PASSWORD
LEA DI,THE_IN_WORD
MOV CX,6
CLD
SUB DX,DX
REPZ CMPSB
JZ ENTRY
DEC BX
JNZ INPUT
MOV AH,4CH
INT 21H
RET
ENTRY:
MOV DX,OFFSET BUF3
MOV AH,9
INT 21H
MOV AH,1
INT 21H
MOV BL,AL
MOV DL,0DH
MOV AH,2
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
CMP BL,''1''
JE P1
CMP BL,''2''
JE P2
CMP BL,''3''
JE P3
CMP BL,''4''
JE TOP4
JMP ENTRY
P1: 
MOV AH,4CH
INT 21H
RET
TOP4:
JMP P4
P2: 
MOV CX,10
LEA SI,ACCOUNT+9
NEXTBIT:
MOV DL,[SI]
OR DL,30H
MOV AH,2
INT 21H
DEC SI
DEC CX  
JNZ NEXTBIT
MOV DX,OFFSET BUF6
MOV AH,9
INT 21H
MOV DL,0DH
MOV AH,2
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
JMP ENTRY
P3:
MOV DX,OFFSET INPUT_MONEY
MOV AH,0AH
INT 21H
MOV DL,[INPUT_MONEY+1]
MOV DH,00H
LEA SI,ACCOUNT
LEA DI,INPUT_MONEY
ADD DI,DX
INC DI
MOV CL,DL
MOV CH,10
MOV AH,00H
ADDNEXTBIT1:
MOV AL,[SI]
MOV BL,[DI]
AND BL,0FH
MOV BH,AH
MOV AH,00H
ADD AL,BH
AAA
ADD AL,BL
AAA
MOV [SI],AL
INC SI
DEC DI
DEC CH
DEC CL
JNZ ADDNEXTBIT1
CMP CH,00H
JZ ADDFINISH
ADDNEXTBIT2:
MOV AL,[SI]
MOV BH,AH
MOV AH,00
ADD AL,BH
AAA
MOV [SI],AL
INC SI
DEC CH
JNZ ADDNEXTBIT2
ADDFINISH:
MOV DX,OFFSET BUF4
MOV AH,9
INT 21H
JMP ENTRY
P4:
MOV DX,OFFSET INPUT_MONEY
MOV AH,0AH
INT 21H
MOV DL,[INPUT_MONEY+1]
MOV DH,00H
LEA SI,ACCOUNT
LEA DI,INPUT_MONEY
ADD DI,DX
INC DI
MOV CL,DL
MOV CH,10
MOV AH,00H
SUBNEXTBIT1:
MOV AL,[SI]
MOV BL,[DI]
AND BL,0FH
MOV BH,AH
MOV AH,00H
SUB AL,BH
AAS
LAHF
MOV DH,AH
SUB AL,BL
AAS
LAHF
OR AH,DH
AND AH,01H
MOV [SI],AL
INC SI
DEC DI
DEC CH
DEC CL
JNZ SUBNEXTBIT1
CMP CH,00H
JZ SUBFINISH
SUBNEXTBIT2:
MOV AL,[SI]
MOV BH,AH
MOV AH,00
SUB AL,BH
AAS
LAHF
AND AH,01H
MOV [SI],AL
INC SI
DEC CH
JNZ SUBNEXTBIT2
SUBFINISH:
MOV DX,OFFSET BUF5
MOV AH,9
INT 21H
JMP ENTRY

MAIN ENDP
CODE ENDS
END START










贴子作者:yuanmh 发贴日期:2001-11-17 22:36
这么简单的用c/c++只要半小时的问题用了这么长的程序
简直最没效率
到处用jump
既不是结构化程序设计,更不是面向对象
为什么要学这东西
不过就靠这程序捞点分了,单靠考试多半不够
总算还是有收获的。
贴子作者:lifanxi 发贴日期:2001-11-17 23:18
To 陈志强:
高手呀!我的感觉是写程序最简单,填充程序比较难,看程序写运行结果最难!写程序至少全是自已的思维,看人家程序就得顺着别人的思维,难!
To Yuanmh:
昨天给你的TD好用吗?这是个调试程序。汇编的编辑软件我一般就用DOS的EDIT,也可以用QuickEdit之类的,汇编软件当然是Masm5了。集成环境的汇编软件也有,比如AsmEdit,它为MASM做了个外壳,不过不好用。
我马上下线仔细研究研究你的程序。

贴子作者:lifanxi 发贴日期:2001-11-19 21:10
通过yuanmh的程序,我发现了本论坛的一BUG,就是输入单引号后,它会变成两个单引号,现已改正。
To Yuanmh:
你的程序好像有点问题,如果帐户没有存钱,选4取钱就会非法操作。
贴子作者:陈志强 发贴日期:2001-11-20 02:06
所以说我只能做最最最最初级的程序读写啊,超过20句的就不要问我了,我连眼睛都不会眨一下的(当然不是对着这个程序)……!!!看看我的帖子!!!
贴子作者:yuanmh 发贴日期:2001-11-20 14:25
其实这程序有3个缺陷:
1 输出高位无效零。
2 加钱超过10位就溢出,没有保护,如9999999999+1=0000000000
3 取钱超过余额无限制,譬如0000000000-1=9999999999
lifanxi 如有兴趣请帮我改一下
贴子作者:lifanxi 发贴日期:2001-11-20 23:03
好呀,我看看吧!不过你写的太乱了。真难看懂!为什么不分几个过程呢?
贴子作者:yuanmh 发贴日期:2001-11-23 23:19
lifanxi
我已经把程序改的差不多了
就高位零去不掉,主要是太麻烦了
quguanqi2.0版如下
DATA SEGMENT
BUF1 DB 'Welcome to use this system.',0DH,0AH,'$'
BUF2 DB 'Please input your password.',0DH,0AH,'$'
BUF3 DB '1. Back to DOS  2. Look up  3. Store money  4. Draw money',0DH,0AH,'$'
BUF4 DB 'store money successfully.',0DH,0AH,0DH,0AH,'$'
BUF5 DB 'draw money successfully.',0DH,0AH,0DH,0AH,'$'
BUF6 DB ' yuan',0DH,0AH,'$'
BUF7 DB 'wrong password',0DH,0AH,'$'
BUF8 DB 'OK!  enter the system',0DH,0AH,'$'
BUF9 DB 'too much money',0DH,0AH,0DH,0AH,'$'
BUF10 DB 'not enough money',0DH,0AH,0DH,0AH,'$'
PASSWORD DB '123456'
IN_WORD DB 7
  DB ?
THE_IN_WORD DB 7 DUP(?)
INPUT_MONEY DB 11
 DB ?
 DB 11 DUP(?)
TEMP DB 10 DUP(?)  
ACCOUNT DB 10 DUP(00H)
DATA ENDS
STACK SEGMENT STACK 'STACK'
DW 50 DUP(?)
TOP LABEL WORD
STACK ENDS
CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX,DATA
   MOV DS,AX
MOV ES,AX
MOV AX,STACK
MOV SS,AX
MOV SP,OFFSET TOP
MOV DX,OFFSET BUF1
MOV AH,9
INT 21H
MOV BX,3
INPUT:
MOV DX,OFFSET BUF2
MOV AH,9
INT 21H
MOV DX,OFFSET IN_WORD
MOV AH,0AH
INT 21H
LEA SI,PASSWORD
LEA DI,THE_IN_WORD
MOV CX,6
CLD
SUB DX,DX
REPZ CMPSB
JZ ENTRE
MOV DX,OFFSET BUF7
MOV AH,9
INT 21H
DEC BX
JNZ INPUT
MOV AH,4CH
INT 21H
RET
ENTRE:
MOV DX,OFFSET BUF8
MOV AH,9
INT 21H
ENTRY:
MOV DX,OFFSET BUF3
MOV AH,9
INT 21H
MOV AH,1
INT 21H
MOV BL,AL
MOV DL,0DH
MOV AH,2
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
CMP BL,'1'
JE P1
CMP BL,'2'
JE P2
CMP BL,'3'
JE P3
CMP BL,'4'
JE TOP4
JMP ENTRY
P1: 
MOV AH,4CH
INT 21H
RET
TOP4:
JMP P4
P2: 
MOV CX,10
LEA SI,ACCOUNT+9
NEXTBIT:
MOV DL,[SI]
OR DL,30H
MOV AH,2
INT 21H
DEC SI
DEC CX  
JNZ NEXTBIT
MOV DX,OFFSET BUF6
MOV AH,9
INT 21H
MOV DL,0DH
MOV AH,2
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
JMP ENTRY
P3:
MOV DX,OFFSET INPUT_MONEY
MOV AH,0AH
INT 21H
MOV DL,[INPUT_MONEY+1]
MOV DH,00H
LEA SI,ACCOUNT
LEA DI,INPUT_MONEY
ADD DI,DX
INC DI
MOV CL,DL
MOV CH,10
MOV AH,00H
ADDNEXTBIT1:
MOV AL,[SI]
MOV BL,[DI]
AND BL,0FH
MOV BH,AH
MOV AH,00H
ADD AL,BH
AAA
ADD AL,BL
AAA
MOV -10[SI],AL
INC SI
DEC DI
DEC CH
DEC CL
JNZ ADDNEXTBIT1
CMP CH,00H
JZ ADDFINISH
ADDNEXTBIT2:
MOV AL,[SI]
MOV BH,AH
MOV AH,00
ADD AL,BH
AAA
MOV -10[SI],AL
INC SI
DEC CH
JNZ ADDNEXTBIT2
ADDFINISH:
CMP AH,1
JZ TOOMUCH
LEA SI,TEMP
LEA DI,ACCOUNT
MOV CX,10
REP MOVSB
MOV DX,OFFSET BUF4
MOV AH,9
INT 21H
JMP ENTRY
TOOMUCH:
MOV DX,OFFSET BUF9
MOV AH,9
INT 21H
JMP ENTRY
P4:
MOV DX,OFFSET INPUT_MONEY
MOV AH,0AH
INT 21H
MOV DL,[INPUT_MONEY+1]
MOV DH,00H
LEA SI,ACCOUNT
LEA DI,INPUT_MONEY
ADD DI,DX
INC DI
MOV CL,DL
MOV CH,10
MOV AH,00H
SUBNEXTBIT1:
MOV AL,[SI]
MOV BL,[DI]
AND BL,0FH
MOV BH,AH
MOV AH,00H
SUB AL,BH
AAS
LAHF
MOV DH,AH
SUB AL,BL
AAS
LAHF
OR AH,DH
AND AH,01H
MOV -10[SI],AL
INC SI
DEC DI
DEC CH
DEC CL
JNZ SUBNEXTBIT1
CMP CH,00H
JZ SUBFINISH
SUBNEXTBIT2:
MOV AL,[SI]
MOV BH,AH
MOV AH,00
SUB AL,BH
AAS
LAHF
AND AH,01H
MOV -10[SI],AL
INC SI
DEC CH
JNZ SUBNEXTBIT2
SUBFINISH:
CMP AH,1
JZ NOTENOUGH
LEA SI,TEMP
LEA DI,ACCOUNT
MOV CX,10
REP MOVSB
MOV DX,OFFSET BUF5
MOV AH,9
INT 21H
JMP ENTRY
NOTENOUGH:
MOV DX,OFFSET BUF10
MOV AH,9
INT 21H
JMP ENTRY
MAIN ENDP
CODE ENDS
END START










贴子作者:lifanxi 发贴日期:2001-11-24 00:55
To Yuanmh:
你效率真是高呀!
几前天忙着复习备考计算方法,没有时间看你的程序,接下来的时间中我应该有空好好研究一下了。
贴子作者:lifanxi 发贴日期:2001-11-24 21:12
要去前置0是很简单的,如果不考虑算法的优劣的话。把输出余额的P2段改成下面的样子,然后在数据段中加一个flag db 0。小写字母是我加的。
这样改过之后,程序的BUG可能就只剩下34功能项如果什么都不输就回车,会非法操作。
P2:
MOV CX,10
LEA SI,ACCOUNT+9
NEXTBIT:
MOV DL,[SI]
cmp flag,1;判断flag是不是为1,Flag为1表示已经输出过数字,这种情况下不能跳过0的输出。
jz skip2
cmp cx,1;判断是不是要输入最低位,如果是,不管前面有没有输出过数字,都要把最低位输出,即处理余额为0的情况。
jz skip2
cmp dl,0;判断将要输出的数字是不是0,如果是,就不要输出。(前面的Flag标志的判断保证了仅仅不输出高位的0,夹在中间的0还是会输出的)
jz skip
skip2:
OR DL,30H
mov flag,1;如果曾经输出过数字,就把flag标志置1。
MOV AH,2
INT 21H
skip:
DEC SI
DEC CX  
JNZ NEXTBIT
MOV DX,OFFSET BUF6
MOV AH,9
INT 21H
MOV DL,0DH
MOV AH,2
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
mov flag,0;输出结束后,把flag置0,为下一次输出做好准备。
JMP ENTRY
贴子作者:yuanmh 发贴日期:2001-11-25 14:03
lifanxi
  我按你的方法把程序改好了,顺便把选34后按ENTER非法操作的问题也改掉了,应该没什么问题了。多谢了。

贴子作者:yuanmh 发贴日期:2001-11-25 14:04
lifanxi
  我按你的方法把程序改好了,顺便把选34后按ENTER非法操作的问题也改掉了,应该没什么问题了。多谢了。


您尚未登陆网站,不能回复贴子!



(C) Copyright 2000-2003 Shengze Middle School Class 4 Grade 3 of the Year 1999