使用MASM以显示该计算中输入字符串信 [英] Using masm to displays the letter that counting in an input string

查看:555
本文介绍了使用MASM以显示该计算中输入字符串信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用MASM(Visual Studio 2010中),编写输入整个文本行,最多132个字符,到缓冲区的程序。然后让我的程序确定每个字母出现的次数。你要统计所有只信A-Z,A-Z和0-9。屏幕应该出把 - 4倍,B - 2次,C-9次

Using masm(Visual Studio 2010), write a program that inputs an entire line of text, up to 132 characters, into a buffer. Then have my program determine how many times each letter of the alphabet occurs. You are to count all letter a-z, A-Z, and 0-9 only. The screen should be out put a - 4 times, b - 2 times, c- 9 times.

推荐答案

我的编译器EMU8086 Intel语法让你的程序(只需复制粘贴运行)。这是大的,但完全注释,帮助您理解,这就是它的作用:显示一个消息用户从键盘(最大132),计数数字和字母(其他被忽略),展示柜捕获的字符串。这是(在code后,更多的解释):

I made your program with compiler EMU8086 Intel syntax (just copy-paste-run). It's big but fully commented to help you understand, this is what it does: display a message for user, capture a string from keyboard (max 132), count digits and letters (other are ignored), display counters. Here it is (more explanations after the code):

.stack 100h
.data

msj1      db 'Enter a line of text (132 max) : $'
text      db 133  ;MAX LENGTH 132, PLUS 1 FOR ENDING CHR(13).
          db ?    ;LENGTH ENTERED BY USER.
          db 133 dup(?)  ;THE STRING.

digits    dw 10 dup(0) ;ARRAY OF 10 COUNTERS FOR DIGITS.
uppercase dw 26 dup(0) ;ARRAY OF 26 COUNTERS FOR UPPERCASE LETTERS.
lowercase dw 26 dup(0) ;ARRAY OF 26 COUNTERS FOR LOWERCASE LETTERS.

str       db 6 dup('$') ;TO STORE NUMBER CONVERTED TO STRING. 
char      db ' =$' 
space     db '  $' 

.code          
;INITIALIZE DATA SEGMENT.
  mov  ax,@data
  mov  ds,ax

;DISPLAY MESSAGE TO CAPTURE LINE OF TEXT.
  mov  ah, 9
  mov  dx, offset msj1
  int  21h

;CAPTURE LINE OF TEXT.  
  mov  ah, 0AH
  mov  dx, offset text
  int  21h

;COUNT CHARACTERS OF THE LINE OF TEXT.
  mov  si, offset text + 2  ;SI POINTS TO BEGINNING OF STRING. THE FIRST 
                            ;2 BYTES ARE FOR CONTROL (MAX LENGTH, LENGTH).
repeat:
;CHECK IF CURRENT CHARACTER IS DIGIT, UPPERCASE OR LOWERCASE.
  mov  bl, [ si ]  ;GET CURRENT CHARACTER.
  call check_digit
  call check_uppercase
  call check_lowercase
;NEXT CHARACTER.
  inc  si
  mov  bl, [ si ]
  cmp  bl, 13
  jne  repeat ;IF NEXT CHARACTER IS NOT 13, REPEAT.

;DISPLAY COUNTERS.
  call clear_screen
  call display_digit_counters    
  call display_uppercase_counters    
  call display_lowercase_counters    

;WAIT FOR A KEY.
  mov  ah,7
  int  21h

;FINISH PROGRAM.
  mov  ax,4c00h
  int  21h                   

;------------------------------------------
;THIS PROCEDURE DISPLAYS THE 10 COUNTERS OF THE
;ARRAY OF COUNTERS FOR DIGITS.

proc display_digit_counters  
  mov  di, offset digits  ;DI POINTS TO ARRAY.
  mov  bp, 10  ;ARRAY LENGTH.
display_digits:
;DISPLAY SPACE.
  mov  ah, 9
  mov  dx, offset space
  int  21h
;CONVERT CURRENT COUNTER IN STRING.
  call dollars
  mov  ax, [ di ]
  call number2string  ;STRING RETURNS IN VARIABLE "STR".
;CONVERT CURRENT COUNTER IN CORRESPONDING DIGIT. FOR
;EXAMPLE, IF CURRENT COUNTER IS 3, CONVERT 3 IN '3'.
  mov  ax, di            ;GET CURRENT COUNTER OFFSET.
  sub  ax, offset digits ;CONVERT TO 0..9.
  shr  ax, 1             ;DIVIDE OFFSET BECAUSE COUNTERS ARE DW.
  add  al, 48            ;CONVERT TO '0'..'9'.
  mov  char, al          ;STORE DIGIT IN STRING TO DISPLAY.
;DISPLAY DIGIT FOR CURRENT COUNTER BELONGS TO.
  mov  ah, 9
  mov  dx, offset char
  int  21h
;DISPLAY CURRENT COUNTER.         
  mov  ah, 9
  mov  dx, offset str
  int  21h
;NEXT COUNTER TO DISPLAY.
  add  di, 2  ;EVERY COUNTER IS DW (TWO BYTES).
  dec  bp
  jnz  display_digits  ;IF ( BP > 0 ) JUMP.

  ret
endp    

;------------------------------------------
;THIS PROCEDURE DISPLAYS THE 26 COUNTERS OF THE
;ARRAY OF COUNTERS FOR UPPERCASE LETTERS.

proc display_uppercase_counters  
  mov  di, offset uppercase  ;DI POINTS TO ARRAY.
  mov  bp, 26  ;ARRAY LENGTH.
display_uppercase:
;DISPLAY SPACE.
  mov  ah, 9
  mov  dx, offset space
  int  21h
;CONVERT CURRENT COUNTER IN STRING.
  call dollars
  mov  ax, [ di ]
  call number2string  ;STRING RETURNS IN VARIABLE "STR".
;CONVERT CURRENT COUNTER IN CORRESPONDING LETTER. FOR
;EXAMPLE, IF CURRENT COUNTER IS 3, CONVERT 3 IN 'D'.
  mov  ax, di            ;GET CURRENT COUNTER OFFSET.
  sub  ax, offset uppercase ;CONVERT TO 0..25.
  shr  ax, 1             ;DIVIDE OFFSET BECAUSE COUNTERS ARE DW.
  add  al, 65            ;CONVERT TO 'A'..'Z'.
  mov  char, al          ;STORE LETTER IN STRING TO DISPLAY.
;DISPLAY LETTER FOR CURRENT COUNTER BELONGS TO.
  mov  ah, 9
  mov  dx, offset char
  int  21h
;DISPLAY CURRENT COUNTER.         
  mov  ah, 9
  mov  dx, offset str
  int  21h
;NEXT COUNTER TO DISPLAY.
  add  di, 2  ;EVERY COUNTER IS DW (TWO BYTES).
  dec  bp
  jnz  display_uppercase  ;IF ( BP > 0 ) JUMP.

  ret
endp    

;------------------------------------------
;THIS PROCEDURE DISPLAYS THE 26 COUNTERS OF THE
;ARRAY OF COUNTERS FOR LOWERCASE LETTERS.

proc display_lowercase_counters  
  mov  di, offset lowercase  ;DI POINTS TO ARRAY.
  mov  bp, 26  ;ARRAY LENGTH.
display_lowercase:
;DISPLAY SPACE.
  mov  ah, 9
  mov  dx, offset space
  int  21h
;CONVERT CURRENT COUNTER IN STRING.
  call dollars
  mov  ax, [ di ]
  call number2string  ;STRING RETURNS IN VARIABLE "STR".
;CONVERT CURRENT COUNTER IN CORRESPONDING LETTER. FOR
;EXAMPLE, IF CURRENT COUNTER IS 3, CONVERT 3 IN 'd'.
  mov  ax, di            ;GET CURRENT COUNTER OFFSET.
  sub  ax, offset lowercase ;CONVERT TO 0..25.
  shr  ax, 1             ;DIVIDE OFFSET BECAUSE COUNTERS ARE DW.
  add  al, 97            ;CONVERT TO 'a'..'z'.
  mov  char, al          ;STORE LETTER IN STRING TO DISPLAY.
;DISPLAY LETTER FOR CURRENT COUNTER BELONGS TO.
  mov  ah, 9
  mov  dx, offset char
  int  21h
;DISPLAY CURRENT COUNTER.         
  mov  ah, 9
  mov  dx, offset str
  int  21h
;NEXT COUNTER TO DISPLAY.
  add  di, 2  ;EVERY COUNTER IS DW (TWO BYTES).
  dec  bp
  jnz  display_lowercase  ;IF ( BP > 0 ) JUMP.

  ret
endp    

;------------------------------------------
;THIS PROCEDURE CHECK IF THE CHARACTER IN BL
;IS A DIGIT ('0'..'9'). IF IT IS, INCREASES
;THE APPROPIATE COUNTER IN ARRAY "DIGITS".

proc check_digit        
  cmp  bl, '0'
  jb   not_a_digit  ;IF AL < '0' FINISH.
  cmp  bl, '9'
  ja   not_a_digit  ;IF AL > '9' FINISH.
;IF NO JUMP, AL IS A DIGIT. INCREASE COUNTER USING
;THE DIGIT AS OFFSET INSIDE THE ARRAY OF COUNTERS,
;FOR EXAMPLE, THE COUNTER FOR DIGIT '3' IS THE THIRD
;POSITION IN THE ARRAY.
  sub  bl, 48  ;CONVERT DIGIT IN NUMBER ('0'..'9'->0..9).
  mov  bh, 0  ;CLEAR BH TO USE BX.                       
  shl  bx, 1  ;MULTIPLY BY 2 BECASE EVERY COUNTER IS DW (2 BYTES).
  add  bx, offset digits  ;BX POINTS TO THE APPROPIATE COUNTER.
  inc  [ bx ]  ;INCREASE COUNTER OF DIGIT.

not_a_digit:
  ret
endp

;------------------------------------------
;THIS PROCEDURE CHECK IF THE CHARACTER IN BL IS
;AN UPPERCASE LETTER ('A'..'Z'). IF IT IS, INCREASE
;THE APPROPIATE COUNTER IN ARRAY "UPPERCASE'.

proc check_uppercase
  cmp  bl, 'A'
  jb   not_uppercase  ;IF AL < 'A' FINISH.
  cmp  bl, 'Z'
  ja   not_uppercase  ;IF AL > 'Z' FINISH.
;IF NO JUMP, AL IS AN UPPERCASE LETTER. INCREASE COUNTER
;USING THE LETTER AS OFFSET INSIDE THE ARRAY OF COUNTERS,
;FOR EXAMPLE, THE COUNTER FOR LETTER 'C' IS THE THIRD
;POSITION IN THE ARRAY.
  sub  bl, 65  ;CONVERT DIGIT IN NUMBER ('A'..'Z'->0..25).
  mov  bh, 0  ;CLEAR BH TO USE BX.
  shl  bx, 1  ;MULTIPLY BY 2 BECASE EVERY COUNTER IS DW (2 BYTES).
  add  bx, offset uppercase  ;BX POINTS TO THE APPROPIATE COUNTER.
  inc  [ bx ]  ;INCREASE COUNTER OF UPPERCASE LETTER.

not_uppercase:
  ret
endp

;------------------------------------------
;THIS PROCEDURE CHECK IF THE CHARACTER IN BL IS
;A LOWERCASE LETTER ('a'..'z'). IF IT IS, INCREASE
;THE APPROPIATE COUNTER IN ARRAY "LOWERCASE".

proc check_lowercase
  cmp  bl, 'a'
  jb   not_lowercase  ;IF AL < 'a' FINISH.
  cmp  bl, 'z'
  ja   not_lowercase  ;IF AL > 'z' FINISH.
;IF NO JUMP, AL IS A LOWERCASE LETTER. INCREASE COUNTER
;USING THE LETTER AS OFFSET INSIDE THE ARRAY OF COUNTERS,
;FOR EXAMPLE, THE COUNTER FOR LETTER 'c' IS THE THIRD
;POSITION IN THE ARRAY.
  sub  bl, 97  ;CONVERT LETTER IN NUMBER ('a'..'z'->0..25).
  mov  bh, 0  ;CLEAR BH TO USE BX.
  shl  bx, 1  ;MULTIPLY BY 2 BECASE EVERY COUNTER IS DW (2 BYTES).
  add  bx, offset lowercase  ;BX POINTS TO THE APPROPIATE COUNTER.
  inc  [ bx ]  ;INCREASE COUNTER OF LOWERCASE LETTER.

not_lowercase:
  ret
endp

;------------------------------------------
;NUMBER TO CONVERT MUST ENTER IN AX.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING.

proc number2string
  mov  bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
  mov  cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:       
  mov  dx, 0 ;NECESSARY TO DIVIDE BY BX.
  div  bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
  push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
  inc  cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
  cmp  ax, 0  ;IF NUMBER IS
  jne  cycle1 ;NOT ZERO, LOOP. 
;NOW RETRIEVE PUSHED DIGITS.
  mov  si, offset str
cycle2:  
  pop  dx        
  add  dl, 48 ;CONVERT DIGIT TO CHARACTER.
  mov  [ si ], dl
  inc  si
  loop cycle2  

  ret
endp  

;------------------------------------------
;FILLS VARIABLE STR WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THESE STRINGS WILL BE DISPLAYED.
proc dollars                 
  mov  si, offset str
  mov  cx, 6
six_dollars:      
  mov  al, '$'
  mov  [ si ], al
  inc  si
  loop six_dollars
  ret
endp  

;------------------------------------------
proc clear_screen
  mov  ah,0
  mov  al,3
  int  10H
  ret
endp

在数据段中,你会发现三个数组:数字,小写和大写。这些是计数器。该想法是使用相同的字符作为阵列内的偏移。例如,数字数组的第一个位置是0位计数器阵列小写的第一个位置是'A'的柜台。

In data segment you'll find three arrays : digits, lowercase and uppercase. These are the counters. The idea is to use the same characters as offset inside the array. For example, the first position of array digits is the counter for digit 0. The first position of array lowercase is the counter for 'a'.

在code在程序结构,其中有些是非常相似:check_digit(check_lowercase,check_uppercase),display_digit_counters(display_lowercase_counters,display_uppercase_counters)

The code is structured in procedures, some of them are very alike: check_digit (check_lowercase, check_uppercase), display_digit_counters (display_lowercase_counters, display_uppercase_counters).

现在对于Visual Studio 2010的C ++控制台项目相同的程序。下一步code必须是复制粘贴在包含的主要方法(code文件INT _tmain(INT ARGC,_TCHAR *的argv []):

#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include <string>
using namespace std;

char msj1[50];
char text[135];
int arr_digits[ 10 ];
int arr_lowercase[ 26 ];
int arr_uppercase[ 26 ];
char str[6];
char charr;
char char_equal;
char space[4];
int idx,i,tmp;

void printspace () {
printf( space );
}
void printstr () {
printf( str );
}
void print_char_equal () {
printf( "%c",char_equal );
}
void print_digit_counter () {
printf( "%d",arr_digits[ i ] );
}   
// THIS PROCEDURE DISPLAYS THE 10 COUNTERS OF THE
// ARRAY OF COUNTERS FOR DIGITS.
void printcharr_digit () {
printf( "%c",i+48 );
}
void display_digit_counters () {
__asm {
  mov  i, 0
display_digits:
  call printspace
  call printcharr_digit
  call print_char_equal
  call print_digit_counter
;NEXT COUNTER TO DISPLAY.
  inc  i
  cmp  i, 10
  jne  display_digits  ;IF ( I != 10 ) JUMP.
}
}
//;THIS PROCEDURE DISPLAYS THE 26 COUNTERS OF THE
//;ARRAY OF COUNTERS FOR UPPERCASE LETTERS.
void printcharr_uppercase () {
printf( "%c",i+65 );
}
void print_uppercase_counter () {
printf( "%d",arr_uppercase[ i ] );
}   

void display_uppercase_counters () {
__asm {
  mov  i, 0
display_uppercase:
  call printspace
  call printcharr_uppercase
  call print_char_equal
  call print_uppercase_counter
;NEXT COUNTER TO DISPLAY.
  inc  i
  cmp  i, 26
  jne  display_uppercase  ;IF ( I != 26 ) JUMP.
}
}
//;THIS PROCEDURE DISPLAYS THE 26 COUNTERS OF THE
//;ARRAY OF COUNTERS FOR LOWERCASE LETTERS.
void printcharr_lowercase () {
printf( "%c",i+97 );
}
void print_lowercase_counter () {
printf( "%d",arr_lowercase[ i ] );
}   

void display_lowercase_counters () {
__asm {
  mov  i, 0
display_lowercase:
  call printspace
  call printcharr_lowercase
  call print_char_equal
  call print_lowercase_counter
;NEXT COUNTER TO DISPLAY.
  inc  i
  cmp  i, 26
  jne  display_lowercase  ;IF ( I != 10 ) JUMP.
}
}
//;THIS PROCEDURE CHECK IF THE CHARACTER IN BL
//;IS A DIGIT ('0'..'9'). IF IT IS, INCREASES
//;THE APPROPIATE COUNTER IN ARRAY "DIGITS".
void inc_digit () {
arr_digits[ idx ]++;
}

void check_digit () {
__asm {
  and  ebx, 0ffh
  cmp  bl, '0'
  jb   not_a_digit  ;IF AL < '0' FINISH.
  cmp  bl, '9'
  ja   not_a_digit  ;IF AL > '9' FINISH.
;IF NO JUMP, AL IS A DIGIT. INCREASE COUNTER USING
;THE DIGIT AS OFFSET INSIDE THE ARRAY OF COUNTERS,
;FOR EXAMPLE, THE COUNTER FOR DIGIT '3' IS THE THIRD
;POSITION IN THE ARRAY.
  sub  bl, 48  ;CONVERT DIGIT IN NUMBER ('0'..'9'->0..9).
  mov  idx, ebx
  call inc_digit

not_a_digit:
}
}
//;THIS PROCEDURE CHECK IF THE CHARACTER IN BL IS
//;AN UPPERCASE LETTER ('A'..'Z'). IF IT IS, INCREASE
//;THE APPROPIATE COUNTER IN ARRAY "UPPERCASE'.
void inc_uppercase () {
arr_uppercase[ idx ]++;
}

void check_uppercase () {
__asm {
  and  ebx, 0ffh
  cmp  bl, 'A'
  jb   not_uppercase  ;IF AL < 'A' FINISH.
  cmp  bl, 'Z'
  ja   not_uppercase  ;IF AL > 'Z' FINISH.
;IF NO JUMP, AL IS AN UPPERCASE LETTER. INCREASE COUNTER
;USING THE LETTER AS OFFSET INSIDE THE ARRAY OF COUNTERS,
;FOR EXAMPLE, THE COUNTER FOR LETTER 'C' IS THE THIRD
;POSITION IN THE ARRAY.
  sub  bl, 65  ;CONVERT DIGIT IN NUMBER ('A'..'Z'->0..25).
  mov  idx, ebx
  call inc_uppercase

not_uppercase:
}
}
//;THIS PROCEDURE CHECK IF THE CHARACTER IN BL IS
//;A LOWERCASE LETTER ('a'..'z'). IF IT IS, INCREASE
//;THE APPROPIATE COUNTER IN ARRAY "LOWERCASE".
void inc_lowercase () {
arr_lowercase[ idx ]++;
}
void check_lowercase  () {
__asm {
  and  ebx, 0ffh
  cmp  bl, 'a'
  jb   not_lowercase  ;IF AL < 'a' FINISH.
  cmp  bl, 'z'
  ja   not_lowercase  ;IF AL > 'z' FINISH.
;IF NO JUMP, AL IS A LOWERCASE LETTER. INCREASE COUNTER
;USING THE LETTER AS OFFSET INSIDE THE ARRAY OF COUNTERS,
;FOR EXAMPLE, THE COUNTER FOR LETTER 'c' IS THE THIRD
;POSITION IN THE ARRAY.
  sub  bl, 97  ;CONVERT LETTER IN NUMBER ('a'..'z'->0..25).
  mov  idx, ebx
  call inc_lowercase
not_lowercase:
}
}

int _tmain(int argc, _TCHAR* argv[])
{
strcpy( msj1,"Enter a line of text (132 max) : " );
char_equal = '=';
strcpy( space,"  " );

printf( msj1 );
scanf( "%s",text );
__asm {

;COUNT CHARACTERS OF THE LINE OF TEXT.
  lea  esi, text  ;SI POINTS TO BEGINNING OF STRING. THE FIRST 
                 ;2 BYTES ARE FOR CONTROL (MAX LENGTH, LENGTH).
repeat:
;CHECK IF CURRENT CHARACTER IS DIGIT, UPPERCASE OR LOWERCASE.
  mov  tmp, esi
  mov  bl, [ esi ]  ;GET CURRENT CHARACTER.
  call check_digit  
  mov  esi, tmp
  mov  bl, [ esi ]  ;GET CURRENT CHARACTER.
  call check_uppercase
  mov  esi, tmp
  mov  bl, [ esi ]  ;GET CURRENT CHARACTER.
  call check_lowercase
  mov  esi, tmp
;NEXT CHARACTER.
  inc  esi
  mov  bl, [ esi ]
  cmp  bl, 0
  jne  repeat ;IF NEXT CHARACTER IS NOT 13, REPEAT.

;DISPLAY COUNTERS.
  call display_digit_counters    
  call display_uppercase_counters    
  call display_lowercase_counters    
}
scanf( "%s",text );
return 0;
}

的Visual Studio 2010不允许使用中断(如int 21H或INT 10H)被用来代替,因此,printf和scanf的。重要提示:注意程序的尊重自上而下的风格,在那里程序必须前(上图),他们被称为声明

Visual Studio 2010 doesn't allow to use interrupts (like int 21h or int 10h), so, printf and scanf are used instead. Important : notice the procedures respect the "top-down" style, where procedures must be declared before (above) they are called.

这篇关于使用MASM以显示该计算中输入字符串信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆