根据其值写入地址

时间:2016-10-12 13:47:49

标签: assembly x86

我被赋予了从相对地址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  

2 个答案:

答案 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.