计算字符数组中的字符频率 - x86 程序集 [英] Counting character frequencies in an array of characters - x86 Assembly

查看:37
本文介绍了计算字符数组中的字符频率 - x86 程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试计算字符串中字符的出现次数.我的代码如下:

I'm trying to count the occurrences of characters in a string. My code is below:

data segment 'DSEG'
    text        db  "This is a sentence.",0     ; string
    textSize    dw  $ - text - 1                ; size of string, - 1 to account for null-termination character
    freqTable   dd  256 DUP(0)
ends 'DSEG'

code segment 'CSEG'
start:                          
mov ax, data        ; set segment registers
mov ds, ax
mov es, ax
;---------------------------------------

sub cx, cx
mov cx, textSize        ; number of times to loop
L1:
    mov ax, [OFFSET text + cx - 1]  ; loop from back using cx, put character in ax
    inc [OFFSET freqTable + 4*ax]   ; increment table's index at the ascii value of character
    LOOP L1

;---------------------------------------
mov ax, 4c00h       ; return to OS
int 21h

ends 'CSEG'
end start           ; set entry point

我制作了一个 DWORDS 数组,其中每个索引代表一个字符.然后我遍历字符串并尝试以每个字符的 ascii 值递增数组.

I made an array of DWORDS where each index would represent a character. I then loop through the string and tried to increment the array at the ascii value of each character.

但是,当我尝试在循环中递增时,我收到了 wrong parameters 错误.我不确定是什么导致了这个错误.我猜我不能只是增加我想要的方式.如何正确创建频率表?我错过了什么小东西吗?

However, I get a wrong parameters error when I try to increment in the loop. I'm not sure what is causing this error. I am guessing I can't just increment the way I'm trying to. How do I properly create the frequency table? Am I missing something small?

推荐答案

为了帮助您了解如何计算字符,我使用 EMU8086(与您的程序集兼容)创建了下一个小程序:该程序要求用户输入文件名,打开文件,读取所有字符并计算它们,然后关闭文件.

To help you understand how to count characters I created next little program with EMU8086 (compatible with your assembly) : the program ask the user for a filename, open the file, read all characters and count them, and close the file.

下图显示了它是如何工作的:有一个具有 256 个位置的频率数组(freq_array").每个位置是对应字符的计数器,例如位置65是'A'的计数器(chr(65)).

Next image shows how it works : there is an array of frequencies ("freq_array") with 256 positions. Each position is the counter of the corresponding char, for example, the position 65 is the counter for 'A' (chr(65)).

每次从文件中读取一个字符时,字符本身将用作偏移量以到达其计数器.例如,如果从文件中读取字符 48 ('0'),则将数字 48 添加到数组偏移量 (offset + 48),并且该位置递增.当文件结束时,它的所有字符都被计数了.

Everytime one char is read from file, the char itself is used as offset to reach its counter. For example, if the char 48 ('0') is read from file, the number 48 is added to the array offset (offset + 48), and that position is incremented. When the file ends, all its chars have been counted.

现在代码:

.model small
.stack 100h

;-----------------------------------------

.data

freq_array   dw 256 dup(0) ;ARRAY OF FREQUENCIES OF EACH ASCII CHARACTER. 

msj          db 13,10,'Enter name of file: $'

filename     db 99        ;MAX NUMBER OF CHARACTERS ALLOWED (98).
             db ?         ;LENGTH (NUMBER OF CHARACTERS ENTERED BY USER).
             db 99 dup(0) ;CHARACTERS ENTERED BY USER. END WITH CHR(13).

filehandler  dw ?         ;FILE HANDLER.

the_char     db ?         ;CHAR READ FROM FILE.

;-----------------------------------------

.code
start:

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

  call get_source_file        ;GET FILE NAME.
  call count_chars            ;FILL FREQ_ARRAY WITH FREQUENCIES OF CHARS.

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

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

;-----------------------------------------

get_source_file proc
;DISPLAY MESSAGE.
  mov dx, offset msj
  mov ah, 9
  int 21h      

;CAPTURE FILENAME FROM KEYBOARD.                                    
  mov ah, 0Ah
  mov dx, offset filename
  int 21h                

;CAPTURED STRING ENDS WITH CHR(13), BUT FILES REQUIRE
;THE FILENAME TO END WITH CHR(0), SO LET'S CHANGE IT.
  mov si, offset filename + 1 ;STRING LENGTH.
  mov cl, [ si ]        ;MOVE LENGTH TO CL.
  mov ch, 0             ;CLEAR CH TO USE CX. 
  inc cx                ;ONE MORE BYTE TO REACH CHR(13).
  add si, cx            ;NOW SI POINTS TO CHR(13).
  mov al, 0
  mov [ si ], al        ;REPLACE CHR(13) BY 0.

  ret
get_source_file endp

;-----------------------------------------
;READ ALL CHARACTERS FROM FILE INCREASING THE COUNTER OF
;EACH CHARACTER IN THE ARRAY OF FREQUENCIES. EACH CHARACTER
;IS USED AS THE OFFSET OF ITS OWN COUNTER, EXAMPLE: THE
;COUNTER FOR 'A' IS THE POSITION 65 OF FREQ_ARRAY.

count_chars proc
;OPEN FILE.
  mov  ah, 3dh          ;SERVICE TO OPEN FILE.
  mov  al, 0            ;OPEN AS READ ONLY.
  mov  dx, offset filename + 2
  int  21h  
  mov  filehandler, ax ;NECESSARY FOR OPERATIONS ON FILE.

;COUNT CHARACTERS.
reading:  
;READ ONE CHAR FROM FILE.
  mov  ah, 3fh          ;SERVICE TO READ FROM FILE.
  mov  bx, filehandler
  mov  cx, 1            ;HOW MANY BYTES TO READ.
  mov  dx, offset the_char ;WHERE TO STORE THE READ BYTES.  
  int  21h              

;CHECK END OF FILE.
  cmp  ax, 0
  je   end_reading      ;IF READ ZERO BYTES, FINISH.

;INCREASE COUNTER. THE CHAR ITSELF IS BEEN USED AS INDEX: THE
;COUNTER FOR CHAR 65 ('A') IS IN THE 65th POSITION OF THE ARRAY.
  mov  si, offset freq_array
  mov  al, the_char     ;USE CHAR AS OFFSET OF ITS OWN COUNTER.
  mov  ah, 0            ;CLEAR AH TO USE AX.
  shl  ax, 1            ;AX * 2, BECAUSE EVERY COUNTER IS 2 BYTES.
  add  si, ax           ;SI POINTS TO COUNTER POSITION.
  inc  [ word ptr si ]  ;INCREMENT COUNTER FOR CURRENT CHAR.
  jmp  reading          ;REPEAT PROCESS.

end_reading:           
;CLOSE FILE.
  mov  ah, 3eh          ;SERVICE TO CLOSE FILE.
  mov  bx, filehandler
  int  21h

  ret
count_chars endp

;-----------------------------------------

end start

希望对您有所帮助.

这是 16 位,因为数组是 DW.要使其与 32 位(数组 DD)兼容,请更改下一行:

This is 16 bits, because the array is DW. To make it compatible with 32 bits (array DD), change next lines:

freq_array   dd 256 dup(0)

shl  ax, 2             ;AX * 4, BECAUSE EVERY COUNTER IS 4 BYTES.

inc  [ dword ptr si ]  ;INCREMENT COUNTER FOR CURRENT CHAR.

这篇关于计算字符数组中的字符频率 - x86 程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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