我是汇编语言的新手,这是一些我不理解的代码,希望有人会帮助它。
DATA SEGMENT
VALUES DB 1,2,3,4,5,6,7,8,9
ITEM DB 6
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DX,AX
LEA SI,VALUES
MOV AL,ITEM
COMPARE: CMP AL,[SI]
JZ Found
INC SI
LOOP COMPARE
CLC
JMP EXIT
Found: STC
EXIT: MOV AH,4CH
INT 21H
ENDS
CODE END
此程序应在(6)
1,2,3,4,5,6,7,8,9
我理解它是如何运作的但我有几个问题:
CLC
和STC
?我知道他们将CF
置于零和一,但我们为什么要使用它?MOV AH,4CH
标签?? EXIT
在开始标签之后我们为什么说以下内容:
MOV AX,DATA
MOV DX,AX
为什么我们不说:
MOV DX,DATA
最后,有人可以推荐一本好书来学习装配吗?
答案 0 :(得分:1)
该算法搜索数字列表中的数字。
如果找到,则设置CF
。如果未找到,则CF
已清除。
INT 21H是MS-DOS服务中断。函数4Ch以AL中的错误代码(包含要找到的数字)结束程序。
DATA SEGMENT
VALUES DB 1,2,3,4,5,6,7,8,9
ITEM DB 6
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DX,AX
LEA SI,VALUES ; DS:SI points to the VALUES structure
MOV AL,ITEM
COMPARE: CMP AL,[SI] ; Compare with number in list
JZ Found ; Jump to Found if equal
INC SI ; Try next
LOOP COMPARE ;
CLC ; Clear CF (not found)
JMP EXIT ; Quit
Found: STC ; Set CF (found)
EXIT: MOV AH,4CH ; End program with error code AL = 6.
INT 21H
ENDS
CODE END
答案 1 :(得分:1)
MOV AX,DATA
MOV DX,AX
这是错误的。
正确答案是:
MOV AX,DATA
MOV DS,AX
我们无法直接从内存向段寄存器(DS)发送数据。所以我们通过通用寄存器(AX)发送。
答案 2 :(得分:0)
MOV AX,DATA
MOV DX,AX
错了。必须是:
MOV AX,DATA
MOV DS,AX
我们将数据段的地址写入DS
寄存器,以便cpu知道要查找我们数据的地址。由于x86指令集限制,我们无法编写MOV DS,DATA
,即在CPU中没有实现这样的功能。每当将段地址写入段寄存器时,您必须使用AX
作为媒介。
答案 3 :(得分:0)
LOOP
指令在这里很奇怪。该指令递减CX
并仅在CX
不为零时跳转。这意味着循环运行CX
次,但程序永远不会设置CX
。
CX
在输入时可能为零,并且第一次递减将使其为65535,因此它实际上将循环最多65536次,如果找不到该元素则搜索超过列表的末尾。
要使其正确,请在循环开始前添加MOV CX, ITEM - VALUES
。由于ITEM
正好在VALUES
之后,减去它们的地址将给出列表中的字节数(元素)。
通常会在列表末尾添加标签,以使此类计算更加健壮。
VALUES DB 1,2,3,4,5,6,7,8,9
VALUES_END LABEL BYTE
; ...
MOV CX, VALUES_END - VALUES
COMPARE: ; ...
LOOP COMPARE
答案 4 :(得分:0)
CLC
指令用于“清除进位标志”,STC
指令用于“设置进位标志”。这些是过程控制指令,用于通过设置/重置标志值来控制处理器操作。MOV AH,4CH
用于终止当前进程。通过将 4CH
的十六进制值存储 (moving=MOV) 到 AH
寄存器中。MOV AX,DATA
MOV DS,AX
MOV AX,DATA
指令是加载 ax 中数据段起始地址的方式。然后通过使用 MOV DS,AX
,数据段被初始化。