我被赋予了从相对地址10h写数字的任务 如果地址是偶数,则按升序排列0-255 如果地址不是
,则从0到255的数字按降序排列然后我们必须总结从地址10h到210h的所有数字 这是我的代码,我不知道它为什么不起作用:
;Write into Address
MOV SI,10h
MOV AL,0d
MOV BX,255
MOV CX,255
LOOP1:
TEST SI,00000001b
jnz notzero
jz zero
notzero:
MOV [SI],BX
DEC BX
INC SI
LOOP LOOP1
zero:
MOV [SI],AL
INC SI
INC AL
LOOP LOOP1
;Sum up address from 10h to 210h
MOV AL,0
MOV SI,10h
MOV cx,200
Loop1:
ADD AL,[SI]
INC SI
LOOP Loop1
答案 0 :(得分:1)
我会用AX来计算你的所有数学。
MOV SI,10h
MOV AX,FF00h ;Or mov ax,0xff00 or however it is written
MOV CX,255 ;One memory write before the loop, 255 writes from the loop
WRITE_512_BYTES:
MOV [SI],AX
DEC AH
INC AL
ADD SI,2
LOOP WRITE_512_BYES
;Sum up address from 10h to 210h
MOV AX,0
MOV BX,0
MOV SI,10h
MOV CX,511 ;One iteration before the loop, 511 loops, 512 bytes summed.
SUM_LOOP:
MOV BL, [SI] ;populate lower byte of bx from memory
ADD AX, BX ;BH guaranteed to still be 0 from earlier MOV
INC SI
LOOP SUM_LOOP
其他评论中讨论过的错误: 1- BX与BL。即使您在BX中具有正确的值(例如,0005h),当您将BX写入内存时,您将同时写入00和05.在您的代码中,您只想写一个字节。我写的代码写了两个字节,但也增加了两个字节。
2-被指出,但不清楚什么记忆"从10h到210h"指的是。如果你被告知检查字节的值"从10h到10h",你会假设你正在检查一个字节 - 一个包含范围,所以10h-10h + 1 = 1。同样,210h-10h + 1 = 201h = 513字节。由于您只写了512个字节,因此可能不正确。您的算法将填充从10h到20Fh的字节。
3-被指出,但是当你用
加上数字时ADD AL,[SI]
您将溢出8位寄存器AL,因为数字的总和对于0-255范围来说太大了。
4-正如所指出的,当LOOP耗尽cx来计数时,它将继续下面的下一条指令。这意味着您的非零情况将开始执行零情况。您可以使用无条件跳转(直接放在LOOP下方)到sum部分来解决这个问题,您需要对其进行标记。
5-我不知道你为什么会遇到mov [si],bl的错误。你确定它输入正确吗?这是一个有效的指令。
尼特:
TEST SI,00000001b
这实际上是AND SI和1并设置了标志,但将1指定为8位值" 00000001b"则很奇怪。实际比较是以16位,32位或64位完成的,具体取决于您运行的模式。考虑将其与1进行比较(并让汇编程序将值扩展为值)而不是将其部分写为8比特价值。
2-当您对两个独立分支中的一个进行比较时,您可以通过测试其中一个案例来逃避。例如,如果您进行测试然后执行
jz zero
您将有条件地跳转到零情况,然后您可以只有非零情况而无需进一步重定向:只需消除jnz指令。
3-知道你在哪里运行这将是一件好事。例如,在16位DOS COM文件中,当您在100h及以上写入字节时,最终会覆盖自己的代码。我假设内存地址对于你写这篇文章的地方都是安全的,因为那是在你的指示中。
答案 1 :(得分:0)
代码中发现的问题用箭头◄■■■
注释:
.model small
.stack 100h
.data
arr db 1024 dup (0) ;◄■■■ BUFFER FOR THE NUMBERS.
.code
mov ax, @data
mov ds, ax
;Write into Address
MOV SI,10h
MOV AL,0d
MOV BL,255 ;◄■■■ BL, NOT BX, BECAUSE BX IS TWO BYTES.
MOV CX,255
LOOP1:
TEST SI,00000001b
jnz notzero
jz zero
notzero:
MOV [SI],BL ;◄■■■ BX IS TWO BYTES, SO WE USE BL INSTEAD.
DEC BL ;◄■■■ BL, NOT BX.
INC SI
LOOP LOOP1
zero:
MOV [SI],AL
INC SI
INC AL
LOOP LOOP1
;Sum up address from 10h to 210h
MOV AX,0 ;◄■■■ AL IS TOO SMALL FOR THE SUM.
MOV SI,10h
MOV cx,200h ;◄■■■ 200H, NOT 200.
MOV BH,0 ;◄■■■ CLEAR BH TO USE BX.
Loop2: ;◄■■■ "LOOP1" WAS ALREADY USED.
MOV BL,[SI] ;◄■■■ EXTRACT ONE BYTE ONLY.
ADD AX,BX ;◄■■■ BH WAS CLEARED, SO BX=BL.
INC SI
LOOP Loop2 ;◄■■■ "LOOP1" WAS ALREADY USED.