我在汇编过程中有一个任务来计算字符串中的单词数,我需要将我的答案保存在cx寄存器中.(我正在使用80x86处理器)
所以我设定:
cx为0 - 这将是我的计数器
bx为0 - 这将是我的索引
我想知道我是否正确使用它,这是我的代码:
.model small
.stack 100h
.data
A db ' this is a test $'
B db 100 dup('$')
.code
mov ax, @data
mov ds, ax
mov cx, 0
mov bx, 0
looping:
cmp A[bx], ' '
jne foundchar
inc bx
jmp looping
foundchar:
inc bx
cmp A[bx], ' '
je foundword
cmp A[bx], '$'
je soff
jmp foundchar
foundword:
inc cx
inc bx
jmp looping
soff:
.exit
end
Run Code Online (Sandbox Code Playgroud)
而我班上的其他人也采用了不同的方式,她将si设置为A的偏移...我并不真正理解这个解决方案:
mov cx,0
mov si, offset A
mov dl,0
next2:
inc si
mov dl,[si]
cmp dl,"$"
JE soff
cmp dl, " "
JE test1 ;if the char is space so lets check what is before the char
jmp next2 ; if the char no space jump back to the loop
test1:
mov al,[si-1]
cmp al, ' '
je next2
add cx,1
jmp next2
soff:
mov al,[si-1]
cmp al,' '
je sofsofi
add cx,1
sofsofi:
.exit
end
Run Code Online (Sandbox Code Playgroud)
请帮助我理解它,以及更合适的方法.
谢谢分配
回答标题中的问题:不可以.使用BX作为索引是不可行的.使用目标索引或源索引(取决于您是否写入或读取数据).使用BX会起作用,但它不被认为是"最佳实践",因为DI和SI的目的是保存索引.
现在的解释是:
尽管(x86)寄存器已命名,但您可以(当然有某些限制)将它们用于与其名称冲突的任务,但它可能导致错误和解释代码时出现问题.
我将尝试在这里写一个简单的初学者注册指南.
限制:
请记住,下面列出的所有寄存器都可以通过在名称中添加E来以扩展(32位)形式使用(例如,EAX是32位版本的累加器,其中低16位包含16位AX).寄存器将按重要性顺序列出(从初学者的角度).
禁止登记!是的,有这样的.
现在启动可怕寄存器的一部分,其中包含令人生畏的名称和复杂的操作.此外,它们没有可用的高位和低位8位(但如果需要,您仍然可以使用位掩码来提取它们).
您可以在这个简洁的指南上阅读更多内容.
至于你的代码,我现在可以给你很少的建议(对于你的脚本的全面检修,你需要等到明天或周一,因为我本周有点忙)
使用SI/DI更好.在你的代码中,A [bx]相当于(A内存地址)+(SI中的值),CPU是非常简单的生物,所以它更喜欢简单的[SI]而不是动态数学.
您可以自行设置数据段,因为它取决于环境(系统/ cpu /仿真器)来设置初始值.虽然将段用于专用内容是个好习惯,但对于这样简单的程序,可以随意在代码段中存储一些数据,它甚至可以通过减少内存跳转和地址计算来加快执行速度.然后你可以写:MOV AX,CS MOV DS,AX(不能直接做).保证Code Segment是您当前代码的代码(否则它将不会执行).
归零寄存器可以更酷!想在AX中加0吗?使用XOR AX,AX(AX = AX exclusive或AX,其逻辑状态将始终为0).它不仅内存更短(更小的代码=更快的加载),它的执行速度也比复制值快(而且现在的CPU足够聪明,可以让它更快).其他优点是风格点.
结果反击?好吧,计数器寄存器是循环计数器而不是数据计数器.对于存储数据DX或BX更直观(BX比DS更多,因为不再需要该寄存器中的数据,因此它"只是变量").但是如果需要CX的结果那么你必须遵守,我想.
嗯,这就是今晚的一切.如果不清楚,请发表评论.
| 归档时间: |
|
| 查看次数: |
764 次 |
| 最近记录: |