好不容易找到您 微机原理编程 跪求帮助

2025-01-01 00:24:32
推荐回答(1个)
回答1:

请参考:
DATA SEGMENT ;定义数据段
BUF DB -3,1,2.... ;定义变量
BUF1 DB 1000 DUP(?) ;预留1000字节的空间
DATA ENDS ;数据段定义结束
CODE SEGMENT ;定义代码段
ASSUME CS:CODE,DS:DATA ;段寄存器关联说明
START: ;代码段第一条指令从这里开始
MOV AX,DATA ;数据段段址→ax
MOV DS,AX ;ax→ds,给数据段段寄存器赋值
LEA SI,BUF ;变量BUF有效地址→SI
MOV CX,1000 ;变量BUF元素个数→CX
MOV AX,[SI] ;变量BUF的第一个字数据→AX
LP: CMP AL,0 ;AL<0?
JL NEXT ;是,转NEXT处执行
INC SI ;变量BUF元素地址增1
DEC CL ;CL-1→CL
JNZ LP ;CL不等于0,转LP处执行循环体
NEXT: MOV BUF1,AL ;AL送变量BUF1保存
MOV AH,4CH ;结束程序
INT 21H ;dos功能调用
CODE ENDS ;代码段定义结束
END START ;编译到此结束

程序段功能: 从变量BUF的1000个有符号字节数种找到第一个负数,把这个负数存于BUF1单元。

从程序段来看,这段程序的编者必是初学汇编语言。提两点建议:

1、有一处错误:
DEC CL
从程序功能来看,此处必须要用:
DEC CX
因为你要从1000个有符号字节数中找出第一个负数,而8位计数器CL能存的最大无符号数是255,那么用指令:
DEC CL
实际上是只从前255个元素中查找,而漏掉了后面的745个元素。如果前255个元素中没有负数,执行结果必然是错误的。

2、Intel 8086/8088体系结构的内存管理是分段式的,教科书及老师都习惯于这种模式,这是正确的。但我们作为初学,只是练习,无论是数据量还是代码量,都很有限,没有必要分这个段、那个段的,完全可以在一个段里进行,即把DS、ES及SS,统统地设置成与代码段同段。下面,以另一种方式来实现这个功能,仅供参考。
CODE SEGMENT
ASSUME CS:CODE,DS:CODE,ES:CODE
BUF DB -3,1,2....
Element equ ($-BUF)/type BUF ;元素个数
BUF1 DB ?
START:push cs
pop ds
push cs
pop es
lea si,BUF
mov cx,Elements
LP: lodsb
cmp al,0
jl $+4
loop LP
MOV BUF1,AL
MOV AH,4CH
INT 21H
CODE ENDS
END START