首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在字符数组中计数字符频率- x86程序集

在字符数组中计数字符频率- x86程序集
EN

Stack Overflow用户
提问于 2015-05-21 12:18:17
回答 2查看 5.9K关注 0票数 5

我正在计算字符串中出现的字符数。我的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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值处增加数组。

但是,当我试图在循环中增加时,我会得到一个wrong parameters错误。我不知道是什么导致了这个错误。我猜我不能像我想要的那样增长。如何正确地创建频率表?我漏掉了什么小东西吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-21 13:06:07

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

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

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

现在代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.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)兼容,请更改下一行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.
票数 3
EN

Stack Overflow用户

发布于 2015-05-24 07:31:05

X86不允许像您一样通过使用AX和CX寄存器进行内存寻址。但是,您可以为此目的使用EAX和ECX。

下一个代码段zero 8,31和zero 16,31将保持为零。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
;---------------------------------------
 xor  eax, eax
 xor  ecx, ecx
 mov  cx, textSize        ; number of times to loop
L1:
 mov  al, [OFFSET text + ecx - 1]
 inc  [OFFSET freqTable + eax*4]
 loop L1
 ;---------------------------------------
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30383575

复制
相关文章
将SSRF升级为RCE
今天我照例要和大家分享一个新的多汁漏洞。 这个问题是在一个私人客户中发现的,所以我们称之为redacted.com。 探索范围。 在列举客户的域为子域的时候,我发现子域[docs]。我发现子域[docs]。 我出来到这个子域[docs.redact.com]。 寻找带外资源负载。 [docs]子域显示了一些文件和统计资料。 当点击一个统计的照片时,我看到了一种奇怪的,但不是一个神奇的链接: 我首先想到的是把[url]的值改为generaleg0x01.com 然后我注意到了[mimeType]参数,所以编辑
Khan安全团队
2021/01/11
2K0
将SSRF升级为RCE
C# 利用.NET 升级助手将.NET Framework项目升级为.NET 6
.NET6 正式版本已经发布有一阵子了,今天我就体验一下如何将.NET Framework的项目升级为.NET 6.
用户9127601
2022/04/19
3.2K0
C# 利用.NET 升级助手将.NET Framework项目升级为.NET 6
使用 .NET 升级助手将NET Core 3.1项目升级为.NET 6
安装升级助手很简单,跟着这个教程开始 https://dotnet.microsoft.com/zh-cn/platform/upgrade-assistant/tutorial/intro:
张善友
2022/06/12
9160
Impala升级为Apache顶级项目
五年前,Cloudera向全世界分享了一个愿景,将通过一个新的SQL引擎Apache Impala(全球第一个也是Hadoop之上最快的MPP SQL引擎)将数十年关系型数据库研究的经验转移到Apache Hadoop平台之上,参考:
Fayson
2018/03/29
9580
Impala升级为Apache顶级项目
KubeVirt升级为CNCF孵化项目
CNCF 技术监督委员会[1](TOC,Technical Oversight Committee)已经投票接受 KubeVirt 作为 CNCF 的孵化项目。
CNCF
2022/06/10
7960
KubeVirt升级为CNCF孵化项目
如何将ubuntu LTS升级为Pro
将被升级的软件包,由 4 个(需要下载 98.9 MB),变为 59 个(需要下载 150 MB)。
zhangrelay
2023/07/27
1.6K0
如何将ubuntu LTS升级为Pro
勒索软件升级,运营模式升级为“三重勒索”
近期沸沸扬扬的、针对Colonial Pipeline发起攻击的勒索软件被FBI确认由DarkSide负责。DarkSide运营着勒索软件即服务(Raas),和许多合作伙伴协作进行攻击,共享赎金收益。
FB客服
2021/07/02
4540
手工将项目升级至 Angular 9 记录
Angular 最近发布了 9.0 版本, 需要先将一个模板项目升级至新版本。 虽然它提供了 ng update 命令来升级, 但是这个命令会自动调整 package.json 文件依赖项的顺序, 导致向其它项目合并时产生不必要的冲突。 为了不打乱现有的依赖项的顺序, 容易向其它派生项目进行合并, 同时也能明确知道究竟那些文件需要修改, 因此采用手工升级的办法。
beginor
2020/08/10
1.8K0
如何将单 master 升级为多 master 集群
前面我们课程中的集群是单 master 的集群,对于生产环境风险太大了,非常有必要做一个高可用的集群(https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/ha-topology/),这里的高可用主要是针对控制面板来说的,比如 kube-apiserver、etcd、kube-controller-manager、kube-scheduler 这几个组件,其中 kube-controller-manager 于 kube-scheduler 组件是 Kubernetes 集群自己去实现的高可用,当有多个组件存在的时候,会自动选择一个作为 Leader 提供服务,所以不需要我们手动去实现高可用,apiserver 和 etcd 就需要手动去搭建高可用的集群的。
我是阳明
2020/09/14
3.4K0
如何将单 master 升级为多 master 集群
Packer 如何将 JSON 的配置升级为 HCL2
在新版本的 Packer 中,如果你需要创建服务器的镜像的话,推荐使用 HCL2 的配置文件。
HoneyMoose
2021/06/24
9640
Packer 如何将 JSON 的配置升级为 HCL2
将React项目从webpack升级到Vite
点击上方“魔术师卡颂”,选择“设为星标” 专注React,学不会你打我! 在之前,已经很多朋友已经升级到了vite,但是大部分都是vue的项目,那么今天我们把之前webpack的react项目升级到
公众号@魔术师卡颂
2021/05/08
3.2K0
将React项目从webpack升级到Vite
将Spring Cloud项目改造为Spring-cloud-kubernetes项目
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/06/13
1.8K0
将Spring Cloud项目改造为Spring-cloud-kubernetes项目
Java设计模式之适配器设计模式(项目升级案例)
 今天是我学习到Java设计模式中的第三个设计模式了,但是天气又开始变得狂热起来,对于我这个凉爽惯了的青藏人来说,又是非常闹心的一件事儿,好了不管怎么样,目标还是目标(争取把23种Java设计模式接触一遍),我在北京向各位问好。老规矩,首先和各位谈谈适配器模式到底是个什么样的设计思想,而且在实际开发中又是如何应用的。        那些官方的概念我就不在这儿粘贴了,请各位自己想想办法。所谓适配器模式,按我意思说吧,其实它的目的就想达到新老兼容,使把原本不能放在一块工作的类或对象能够让它们同时使用起来,举个
赵小忠
2018/01/24
1.2K0
自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference
发布于 2018-04-24 10:03 更新于 2018-06-29 08:52
walterlv
2018/09/18
1.8K0
自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference
【1/25】将Game改写为单例模式(Singleton Pattern)
Game的实例在游戏时只有一个,现在我们首先将Game类改造为一个单例。所谓单例,就是运行时只有一个实例。Game.js代码改造如下:
LIYI
2021/02/23
4500
(四) 如何将socket设置为非阻塞模式
1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af, _In_ int type, _In_ int protocol ); SOCKET WSASocket( _In_ int af, _In_ int type, _In_ int
范蠡
2018/04/04
4.6K0
如何将MySQL GR 设置为多主模式
在MySQL 5.7.17版本中发布的MySQL Group Replication(后文简称为MGR)被很多人称为MySQL复制方案的正规军,可以一举取代现在的MySQL Replication,Semisynchronous replication,甚至是可以取代之前最成功的MySQL集群方案Galera。 MGR有两种模式,一种是Single-Primary,一种是Multi-Primary,单主或者多主。 在前一种模式Single-Primary中,无论集群中有多少个节点,只有一个节点允许写入,其它
数据和云
2018/03/07
3.9K0
如何将MySQL GR 设置为多主模式
升级为Rust,Hive勒索软件加密将变得更加复杂
近期,微软安全部门的研究人员发现了一种名为Hive的升级版勒索软件服务(RaaS),随即安全专家在周二的一份报告中概述了他们的发现,在报告中,专家们阐述了以下观点:随着其最新版本的几个重大升级,Hive也证明了它是发展最快的勒索软件家族之一,也例证了不断变化的勒索软件生态系统。 根据微软的说法,Hive勒索软件最新版本的升级代表着对整个勒索软件基础架构的彻底改革,在报告中,专家们还指出最值得注意的变化,包括将完整的代码迁移到另一种编程语言(从GoLang迁移到Rust),以及使用更复杂的加密方法。 Hive
FB客服
2023/03/30
3270
升级为Rust,Hive勒索软件加密将变得更加复杂
次世代的会话管理项目 Spring Session
原文作者:Adib Saikali 原文地址:https://www.infoq.com/articles/Next-Generation-Session-Management-with-Spring
Techeek
2018/06/25
1K0
点击加载更多

相似问题

将正常项目升级为Xamarin.Forms项目

11

数独项目无法为按钮分配级别

10

单元测试数独-测试应该尝试独立于数独板的数据结构吗?

16

将旧go项目升级为使用go模块

13

会话项目始终为空

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文