assembly - 需要帮助将正确的结果输入 0500 地址
问题描述
编写一个汇编语言程序,在内存位置 F454h - F503h 中向后搜索包含小写“a”的 ASCII 值的内存位置,并将总数放入位置 0500h。让程序从内存中的 0200h 开始。组装程序,将其加载到模拟器中,运行它,并验证它是否正常工作。
org 0200h
ldx #0d
stx 0500h
dex
环形:
lda 0F454h,x
cmp #'a'
bne NotA
inc 0500h
不是:
dex
cpx #176d
bne Loop
brk
end
当我通过评分器运行此程序时,我没有得到正确的结果,因此感谢您的帮助。
解决方案
有两件事需要考虑。
- 您希望起始地址为 F503h,结束地址为 F454h。
- 理想情况下,您的循环退出条件应该测试索引为零或负数(BNE 或 BPL)。这样您就可以避免使用比较 (CPX)。
如果您测试是否定的,那基本上意味着设置了最高位。当索引 (X) 从 00h 递减到 FFh 时,最高位被设置。
最好测试负数,因为索引 (X) 的最后一个值为零 - 这使得计算要使用的地址(对于 LDA 地址,X)更加明显。
然而,测试是否定的意味着 X 的最大值可以是 80h (128)。这是因为所有高于 7Fh (127) 的值都设置了最高位。如果您从 80h 开始,那么第一个减量 (DEX) 会将索引变为非负数的 7Fh,因此循环很好。如果您从 81h 开始,那么 DEX 会将索引设为 80h,这是负数(设置了最高位),因此循环立即退出,这很糟糕。
那么我们可以测试阴性吗?在这种情况下,这是不可能的。这是因为索引值的范围是 F503h - F454h + 1= 176(不同的地址)。而且,这高于 128。
所以我们被迫检查为零。这意味着在我们退出循环之前索引 (X) 的最后一个值将是 1。
反过来,由于我们想在循环结束时到达地址 F454h,我们必须从中减去 1——因为我们从索引 (X) 中加 1。所以我们需要:
LDA F453h, X
我们从 X 的什么值开始?也就是说,我们需要在 F453h 上加多少才能得到 F503h?这是 F503h - F453h = 176:
LDX #176d
由于 X 一开始不是零,我们需要将位置 0500h 单独设置为零(或 65C02 上的 STZ 0500h):
LDA #0d
STA 0500h
最终算法变为(我更喜欢大写):
ORG 0200h
LDA #0d
STA 0500h
LDX #176d
Loop:
LDA F453h,X
CMP #'a'
BNE NotA
INC 0500h
NotA:
DEX
BNE Loop
BRK
作业奖励:你能让循环执行得更快吗?
推荐阅读
- java - 从 S3 解压缩并读取 gz 文件 - Scala
- spring-security - spring-security saml2:如何获取当前用户?
- javascript - 如何修复 onSnapshot 中的未捕获错误:FirebaseError:查询需要索引。关于动态排序?
- ruby-on-rails - Redmine 插件开发 - 如何避免插件之间重复的表名和模型名
- html - 背景图像调整高度
- java - 'JsonSyntaxException:com.google.gson.stream.MalformedJsonException:第 1 行第 30 列的未终止对象'
- docker - 无交换限制支持 - docker 引擎
- google-colaboratory - rfind() 似乎在 Google Colab 中不起作用
- c# - 数组拆分场景
- javascript - How do I combine two objects based off unique similarities in key names?