好吧,我开始像一个月前开始学习8086汇编,直到现在我学习它没有太多问题,但现在我被困在字符串中。问题是如何在8086中迭代字符串并操纵字符?此外,我有一个任务,我的微处理器课程删除给定字符串中的所有'字符(我的代码中的字符串“proce'so'r”),然后比较新获得的字符串与第一个字符串,并检查它们是否相等。事情是我甚至不知道如何迭代它。这真的没有在课堂上解释,所以我在这里寻求帮助。这是我的代码到目前为止(仅用于字符串迭代和打印字符,它不起作用,不知道为什么):
data segment
string db "proce'so'r"
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
lea di, string
mov cx, 10
for:
cmp cx, 0
je end
mov dl, [di]
mov ah, 02h
int 21h
inc di
loop for
end:
mov ax, 4c00h
int 21h
ends
end start
答案 0 :(得分:0)
扩展我的评论:一个更有效的循环结构将是:
data segment
string db "proce'so'r"
stringlen equ $-string ; subtract current string's address from current address
ends
start:
mov ax, data
mov ds, ax ; Assuming rkhb is correct about segments
lea di, string
mov cx, stringlen ; having the assembler generate this constant from the length of the string prevents bugs if you change the string
;; if stringlen can be zero:
; test cx,cx
; jz end
;; .labels are "local" and don't end up as symbols in the object file, and don't have to be unique across functions
;; emu8086 may not support them, and this Q is tagged as 8086, not just 16bit DOS on a modern CPU.
print_loop:
mov dl, [di]
mov ah, 02h ; If int21h doesn't clobber ah, this could be hoisted out of the loop. IDK.
int 21h
inc di
dec cx
jg print_loop ; or jne
end:
; Or save a register (and the mov to initialize it) with
; cmp di, offset string+stringlen
; jb print_loop
;; loop print_loop ; or save instruction bytes, but slower on modern CPUs
mov ax, 4c00h
int 21h
处理字符串的一种更常见的方法是使用零字节终止它们。所以循环绑定将是test dl,dl / jnz
,不需要计数器。
另外,请注意,使用si
作为源指针并使用di
作为dest指针是典型的。
您可以通过执行
来跳过某个字符来复制字符串 mov dl, [si]
inc si
cmp dl, '\'' ; or write the value as a hex constant instead of a character literal
je nocopy
mov [di], dl
inc di
nocopy:
作为循环的一部分。在循环开始时,你希望si指向输入字符串中的第一个字符,而di指向一个足以保存结果的缓冲区。要跳过的字符可以在寄存器中,而不是硬编码为cmp
的直接操作数。
如果你真的想以现代CPU的速度为代价来节省代码字节,你可以使用字符串移动指令lodsb
/ stosb
,除了它们加载到/存储来自{ {1}}。
答案 1 :(得分:0)
您需要初始化DS以使用定义的数据段。
完整解决方案:
DATA SEGMENT
STRING DB "PROCE'SO'R"
ENDS
STACK SEGMENT
DW 128 DUP(0)
ENDS
CODE SEGMENT
START:
MOV AX,@DATA
MOV DS,AX
LEA DI, STRING
MOV CX, 10H
FOR:
CMP CX, 0
JE END
MOV DL, [DI]
MOV AH, 02H
INT 21H
INC DI
LOOP FOR
END:
MOV AX, 4C00H
INT 21H
ENDS
END START
在开始之后注意以下内容:
MOV AX,@DATA
MOV DS,AX