[原创]

parmhan 2009-01-16 02:28:30
学习汇编的前八章也应该试着将学习的内容总结和练习一下了。这个程序只注重功能,没有充分
考虑算法。虽然是个小程序,也感觉到编写起来很费事(用惯了高级语言写程序,这次什么都要
自己从头来构建,思维上的确不容易接受)。不过写完这个小程序后,感觉非常的有趣。也让自
己在机器思维的道路上前进了一小步。说实话很兴奋。原来不屑一顾的汇编,现在竟然又检起来
,应该说又从头开始。虽然这个程序功能非常简单,自己感觉有点拿不出手,但是为了使自己的
技术能够更加稳步的提升,现在晾出来和大家交流,讨论。请路过的大大不要见笑。如有不妥的
地方还希望指正赐教。在此感激不尽。因为只有发现问题,解决问题,才能使自己的水平不断的
提升。

;**************************************************************
;程序功能:显示输入字符串字符个数
;编译环境:MASM611下编译通过
;程序作者:Parmhan
;**************************************************************

TITLE STRING_LENGHT(EXE) 显示输入的字符串的字符个数(以十进制)
.MODEL SMALL
.STACK 256
;===========================================
.DATA
;===========================================
; 这里我们不用这个结构,只利用输入字符缓存区
PARLIST LABEL BYTE ;定义输入结构
MAXNLEN DB 40 ;输入最大字符个数
ACTULEN DB ? ;实际输入字符个数
INPUT_DATA DB 40 DUP(' ') ;键盘输入字符缓冲区
;-----------------------------------------------------------------------------
TITLE_INPUT DB 'Please Input:',0DH
TITLE_ERROR DB 'Input charactor error,please retry!',0DH
DATA_TEMP DW ? ;数据临时变量
DATA_BUFFER DB 40 DUP(0) ;数据转换缓冲区
DATA_BIT DB ? ;记录数据位数
DATA_LEN DB ?
;============================================
.386
.CODE
;---------------------------------------------------------------------------
; MAIN :程序入口函数
;---------------------------------------------------------------------------
MAIN PROC FAR

MOV AX,@DATA
MOV DS,AX

CALL CLEARSCREEN ;清屏

LEA DX,TITLE_INPUT
PUSH DX
CALL STRLEN ;计算字符个数

PUSH AX
PUSH DX
CALL PRINT ;打印输入提示符

MOV AH,0AH ;请求键盘输入
LEA DX,INPUT_DATA
INT 21H

PUSH DX
CALL CONVERTBUFFER ;整理字符输入缓冲区

LEA DX,INPUT_DATA
PUSH DX
CALL STRLEN

PUSH AX
CALL CONVERTASCII

PUSH AX
CALL SETCURSOR

LEA DX,DATA_BUFFER
PUSH DX
CALL STRLEN

LEA DX,DATA_BUFFER
PUSH AX
PUSH DX
CALL PRINT

MOV AX,4C00H
INT 21H
MAIN endp
;---------------------------------------------------------------------------
; PRINT:显示传入的字符串
; 参数:szBuffer 传入的字符串缓冲区
; 参数:iLen 传入字符个数
;---------------------------------------------------------------------------
PRINT PROC NEAR

PUSH BP
MOV BP,SP
PUSHAD

XOR SI,SI
MOV SI,[BP+4]
XOR BX,BX
MOV BX,[BP+6]

MOV AL,'$'
MOV [SI+BX],BYTE PTR AL

MOV AH,09 ;请求屏幕输出
MOV DX,SI
INT 21H

POPAD
POP BP
ret 4
PRINT endp
;---------------------------------------------------------------------------
; STRLEN:检查字符串长度
; 参数:szBuffer 传入要检测的字符串地址
; 返回值:返回字符长度。放在AX中
;---------------------------------------------------------------------------
STRLEN PROC NEAR

PUSH BP
MOV BP,SP
MOV SI,[BP+4]

MOV AL,BYTE PTR [SI]
XOR BX,BX
A10:
CMP AL,0DH
JZ A20
INC BX
INC SI
MOV AL,BYTE PTR [SI]
JMP A10
A20:
MOV AX,BX
POP BP
ret 2
STRLEN endp
;---------------------------------------------------------------------------
; COVERTASCII:将HEX转换成ASCII十进制字符串
; 参数:Numeric 要转换的16进制数字
; 返回值:返回字符长度。放在DATA_BUFFER中并已0DH结尾
;---------------------------------------------------------------------------
CONVERTASCII PROC NEAR

PUSH BP
MOV BP,SP
PUSHAD

XOR DX,DX
MOV AX,[BP+4]
LEA SI,DATA_BUFFER
MOV DATA_TEMP,AX
MOV BX,2710H
A10:
DIV BX
CMP AX,0
JNZ A20
JZ A30
A20:
ADD AX,30H
MOV [SI],BYTE PTR AL
INC SI
MOV DATA_TEMP,DX
A30:
MOV AX,BX
MOV BX,000AH
XOR DX,DX
DIV BX

CMP AX,0
JZ A40
MOV BX,AX
XOR AX,AX
XOR DX,DX
MOV AX,DATA_TEMP
JMP A10
A40:
MOV AL,0DH
MOV [SI],BYTE PTR AL

POPAD
POP BP
ret 2
CONVERTASCII endp
;---------------------------------------------------------------------------
; CLEARSCREEN:清屏
; 参数:无
; 返回值:无
;---------------------------------------------------------------------------
CLEARSCREEN PROC NEAR

PUSHAD

MOV AX,0600H ;请求卷屏
MOV BH,07H
MOV CX,0000H
MOV DX,184FH
INT 10H

POPAD
ret
CLEARSCREEN endp
;---------------------------------------------------------------------------
; SETCURSOR:设置光标
; 参数:STRING_LENGTH 显示的字符串长度
; 返回值:无
;---------------------------------------------------------------------------
SETCURSOR PROC NEAR

PUSH BP
MOV BP,SP
PUSHAD

XOR BX,BX
MOV AX,004FH ;列数
MOV CX,0018H ;行数
MOV BX,[BP+4]

SUB AX,BX
SHR AX,1
MOV BX,AX
SHR CX,1

MOV AH,02H ;请求设置光标
MOV BH,00
MOV DH,CL
MOV DL,BL
INT 10H

POPAD
POP BP
ret 2
SETCURSOR endp
;---------------------------------------------------------------------------
; CONVERTBUFFER:整理缓存,将字符输入缓存重新整理
; 参数:INPUTBUFFER 输入缓存
; 返回值:无
;---------------------------------------------------------------------------
CONVERTBUFFER PROC NEAR

PUSH BP
MOV BP,SP
PUSHAD

MOV SI,[BP+4]
MOV DI,SI
ADD SI,2 ;输入缓存前两位为数据位

XOR AX,AX
MOV AL,BYTE PTR [SI]
XOR DX,DX
C10:
CMP AL,20H
JB C20
CMP AL,7EH
JA C20
CMP AL,0DH
JZ C20
MOV [DI],BYTE PTR AL
INC SI
MOV AL,BYTE PTR [SI]
INC DI
INC DX
JMP C10
C20:
MOV AL,0DH
MOV [DI],BYTE PTR AL

POPAD
POP BP
ret 2
CONVERTBUFFER endp
;===============================================
END MAIN

...全文
211 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
xtdumpling 2009-01-17
  • 打赏
  • 举报
回复
小补充一下:
;************************************************************** 
;程序功能:显示输入字符串字符个数
;编译环境:MASM611下编译通过
;程序作者:Parmhan
;**************************************************************

TITLE STRING_LENGHT(EXE) 显示输入的字符串的字符个数(以十进制)
.MODEL SMALL
.STACK 256
;===========================================
.DATA
;===========================================
PARLIST LABEL BYTE ;定义输入结构
MAXNLEN DB 40 ;输入最大字符个数
ACTULEN DB ? ;实际输入字符个数
INPUT_DATA DB 40 DUP(' ') ;键盘输入字符缓冲区
;-----------------------------------------------------------------------------
TITLE_INPUT DB 'Please Input:',0DH
TITLE_ERROR DB 'Input charactor error,please retry!',0DH
DATA_TEMP DW ? ;数据临时变量
DATA_BUFFER DB 40 DUP(0) ;数据转换缓冲区
DATA_BIT DB ? ;记录数据位数
DATA_LEN DB ?
;============================================
.386
.CODE
;---------------------------------------------------------------------------
; MAIN :程序入口函数
;---------------------------------------------------------------------------
MAIN PROC FAR

MOV AX,@DATA
MOV DS,AX

CALL CLEARSCREEN ;清屏

LEA DX,TITLE_INPUT
PUSH DX
CALL STRLEN ;计算字符个数

PUSH AX
PUSH DX
CALL PRINT ;打印输入提示符

MOV AH,0AH ;请求键盘输入
; LEA DX,INPUT_DATA
LEA DX,PARLIST;;;
INT 21H

; PUSH DX
; CALL CONVERTBUFFER ;整理字符输入缓冲区

; LEA DX,INPUT_DATA
; PUSH DX
; CALL STRLEN
XOR AX,AX
MOV AL,ACTULEN;;;

PUSH AX
CALL CONVERTASCII

PUSH AX
CALL SETCURSOR

LEA DX,DATA_BUFFER
PUSH DX
CALL STRLEN

LEA DX,DATA_BUFFER
PUSH AX
PUSH DX
CALL PRINT

MOV AX,4C00H
INT 21H
MAIN endp
;---------------------------------------------------------------------------
; PRINT:显示传入的字符串
; 参数:szBuffer 传入的字符串缓冲区
; 参数:iLen 传入字符个数
;---------------------------------------------------------------------------
PRINT PROC NEAR

PUSH BP
MOV BP,SP
PUSHAD

XOR SI,SI
MOV SI,[BP+4]
XOR BX,BX
MOV BX,[BP+6]

MOV AL,'$'
MOV [SI+BX],BYTE PTR AL

MOV AH,09 ;请求屏幕输出
MOV DX,SI
INT 21H

POPAD
POP BP
ret 4
PRINT endp
;---------------------------------------------------------------------------
; STRLEN:检查字符串长度
; 参数:szBuffer 传入要检测的字符串地址
; 返回值:返回字符长度。放在AX中
;---------------------------------------------------------------------------
STRLEN PROC NEAR

PUSH BP
MOV BP,SP
MOV SI,[BP+4]

MOV AL,BYTE PTR [SI]
XOR BX,BX
A10:
CMP AL,0DH
JZ A20
INC BX
INC SI
MOV AL,BYTE PTR [SI]
JMP A10
A20:
MOV AX,BX
POP BP
ret 2
STRLEN endp
;------------------------------------------------------------------------------
; COVERTASCII:将HEX转换成ASCII十进制字符串
; 参数:Numeric 要转换的16进制数字
; 返回值:返回字符长度。放在DATA_BUFFER中并已0DH结尾
;------------------------------------------------------------------------------
CONVERTASCII PROC NEAR

PUSH BP
MOV BP,SP
PUSHAD

XOR DX,DX
MOV AX,[BP+4]
LEA SI,DATA_BUFFER
MOV BX,000AH
C10:
DIV BX
CMP AX,BX
JB C20
INC CX
ADD DX,30H
MOV [SI],BYTE PTR DL
INC SI
XOR DX,DX
JMP C10
C20:
TEST AX,-1
JZ C30
ADD AX,30H
MOV [SI],BYTE PTR AL
INC SI
C30:
ADD DX,30H
MOV [SI],BYTE PTR DL
INC SI
MOV AX,000DH
MOV [SI],BYTE PTR AL



POPAD
POP BP
ret 2

CONVERTASCII endp
;---------------------------------------------------------------------------
; CLEARSCREEN:清屏
; 参数:无
; 返回值:无
;---------------------------------------------------------------------------
CLEARSCREEN PROC NEAR

PUSHAD

MOV AX,0600H ;请求卷屏
MOV BH,07H
MOV CX,0000H
MOV DX,184FH
INT 10H

POPAD
ret
CLEARSCREEN endp
;---------------------------------------------------------------------------
; SETCURSOR:设置光标
; 参数:STRING_LENGTH 显示的字符串长度
; 返回值:无
;---------------------------------------------------------------------------
SETCURSOR PROC NEAR

PUSH BP
MOV BP,SP
PUSHAD

XOR BX,BX
MOV AX,004FH ;列数
MOV CX,0018H ;行数
MOV BX,[BP+4]

SUB AX,BX
SHR AX,1
MOV BX,AX
SHR CX,1

MOV AH,02H ;请求设置光标
MOV BH,00
MOV DH,CL
MOV DL,BL
INT 10H

POPAD
POP BP
ret 2
SETCURSOR endp
;---------------------------------------------------------------------------
; CONVERTBUFFER:整理缓存,将字符输入缓存重新整理
; 参数:INPUTBUFFER 输入缓存
; 返回值:无
;---------------------------------------------------------------------------
CONVERTBUFFER PROC NEAR

PUSH BP
MOV BP,SP
PUSHAD

MOV SI,[BP+4]
MOV DI,SI
ADD SI,2 ;输入缓存前两位为数据位

XOR AX,AX
MOV AL,BYTE PTR [SI]
XOR DX,DX
C10:
CMP AL,20H
JB C20
CMP AL,7EH
JA C20
CMP AL,0DH
JZ C20
MOV [DI],BYTE PTR AL
INC SI
MOV AL,BYTE PTR [SI]
INC DI
INC DX
JMP C10
C20:
MOV AL,0DH
MOV [DI],BYTE PTR AL

POPAD
POP BP
ret 2
CONVERTBUFFER endp
;===============================================
END MAIN
parmhan 2009-01-17
  • 打赏
  • 举报
回复
再次谢谢xtdumpling 的指出问题。这次将所提的问题进行了更正,希望在测试一下。应该没有问题了。呵呵,汇编果然用起来很过瘾。爽。。。。

;------------------------------------------------------------------------------
; COVERTASCII:将HEX转换成ASCII十进制字符串
; 参数:Numeric 要转换的16进制数字
; 返回值:返回字符长度。放在DATA_BUFFER中并已0DH结尾
;------------------------------------------------------------------------------
CONVERTASCII PROC NEAR

PUSH BP
MOV BP,SP
PUSHAD

XOR DX,DX
MOV AX,[BP+4]
LEA SI,DATA_BUFFER
MOV BX,000AH
C10:
DIV BX
CMP AX,BX
JB C20
INC CX
ADD DX,30H
MOV [SI],BYTE PTR DL
INC SI
XOR DX,DX
JMP C10
C20:
TEST AX,-1
JZ C30
ADD AX,30H
MOV [SI],BYTE PTR AL
INC SI
C30:
ADD DX,30H
MOV [SI],BYTE PTR DL
INC SI
MOV AX,000DH
MOV [SI],BYTE PTR AL



POPAD
POP BP
ret 2

CONVERTASCII endp
WizardBear 2009-01-17
  • 打赏
  • 举报
回复
还是喜欢dos和汇编那个时代,什么都是简单直接的,
现在的coding行业让这几个商业味儿浓厚的软硬件公司给引导的一团乱糟糟,
这些公司只有一个目的:创造概念,然后在这个概念上领先,挣钱!
parmhan 2009-01-17
  • 打赏
  • 举报
回复
已经拜读了,写的很简练。学习了。。。。。。
moli2009 2009-01-17
  • 打赏
  • 举报
回复
真羡慕呀.
parmhan 2009-01-17
  • 打赏
  • 举报
回复
有改进了,等陪老婆逛完商店在回来研究研究!
xtdumpling 2009-01-17
  • 打赏
  • 举报
回复
再改短一点:
Title display char count of input string
.model small
.386
.stack 40h
.data
MAXCOUNT EQU 41h

TITLEStr DB 'Please Input:','$'

PARLIST LABEL BYTE ;定义输入结构
MAXNLEN DB MAXCOUNT ;输入最大字符个数
ACTULEN DB ? ;实际输入字符个数
INPUT_DATA DB MAXCOUNT DUP('?') ;键盘输入字符缓冲区
.code
.startup

CALL ClearScreen

LEA DX, TITLEStr
CALL DispString

LEA DX, PARLIST
CALL GetString

CALL DispCrLf

MOV AL, ACTULEN
CALL DispHex2Dec

.exit
;-----------------------------
;IN : none
;OUT: none
;modify: none
ClearScreen proc uses AX BX CX DX
MOV AH, 6
XOR AL, AL
XOR CX, CX
MOV DH, 24
MOV DL, 79
MOV BH, 7
INT 10h
RET
ClearScreen endp

;IN : DS:DX=string address
;OUT: none
;modify: none
DispString proc uses AX DX
MOV AH, 09
INT 21h
RET
DispString endp

;IN : DS:DX=string buffer structure
;OUT: none
;modify: none
GetString proc uses AX
MOV AH, 0Ah
INT 21h
RET
GetString endp

;IN : AL=Hex to convert and display
;OUT: none
;modify: none
DispHex2Dec proc uses AX BX
XOR AH, AH
MOV BL, 100
DIV BL
OR AL, AL
JZ @F
CALL DispHex4
@@:
MOV AL, AH
XOR AH, AH
MOV BL, 10
DIV BL
OR AL, AL
JZ @F
CALL DispHex4
@@:
MOV AL, AH
CALL DispHex4

RET
DispHex2Dec endp

;IN : AL=4 bits Hex to display
;OUT: none
;modify: none
DispHex4 proc uses AX

AND AL, 0Fh
CMP AL, 09
JBE @F
ADD AL, 7
@@:
ADD AL, 30h
CALL DispChar

RET
DispHex4 endp

;IN : AL=char to display
;OUT: none
;modify: none
DispChar proc uses AX DX
MOV DL, AL
MOV AH, 2
INT 21h
RET
DispChar endp

;IN : none
;OUT: none
;modify: none
DispCrLf proc uses AX
MOV AL, 0Dh
CALL DispChar

MOV AL, 0Ah
CALL DispChar
RET
DispCrLf endp
end
parmhan 2009-01-16
  • 打赏
  • 举报
回复
过程已修改,补上。多谢楼上xtdumpling
;------------------------------------------------------------------------------
; COVERTASCII:将HEX转换成ASCII十进制字符串
; 参数:Numeric 要转换的16进制数字
; 返回值:返回字符长度。放在DATA_BUFFER中并已0DH结尾
;------------------------------------------------------------------------------
CONVERTASCII PROC NEAR

PUSH BP
MOV BP,SP
PUSHAD

XOR DX,DX
MOV AX,[BP+4]
LEA SI,DATA_BUFFER
MOV DATA_TEMP,AX
MOV BX,2710H

A10:
DIV BX
CMP AX,0
JNZ A20
JZ A30

A20:
ADD AX,30H
MOV [SI],BYTE PTR AL
INC SI
MOV DATA_TEMP,DX
A30:
MOV AX,BX
MOV BX,000AH
XOR DX,DX
DIV BX

CMP AX,0
JZ A40
MOV BX,AX
XOR AX,AX
XOR DX,DX
MOV AX,DATA_TEMP
CMP AX,0AH
JB A20
JMP A10
A40:
MOV AL,0DH
MOV [SI],BYTE PTR AL
POPAD
POP BP
ret 2

CONVERTASCII endp
parmhan 2009-01-16
  • 打赏
  • 举报
回复
问题就出在将16进制数转换10进制数字ASCII字符哪个函数部分。忽略了10、20、30这些整数。马虎了,稍后将函数CONVERTASCII做一下修改。
xtdumpling 2009-01-16
  • 打赏
  • 举报
回复
支持!

我输入: Good Luck!
怎么输出:1 ??

字符个数10,20,30...都显示不对.
parmhan 2009-01-16
  • 打赏
  • 举报
回复
忘加标题了补上:汇编实现输入字符串以十进制数字输出字符个数
希望版主能加上。谢谢
xtdumpling 2009-01-16
  • 打赏
  • 举报
回复
我输入Good
输出: 4000 ??

21,500

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧