0

好的,我一个月前开始学习 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
4

2 回答 2

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


您可以在跳过某个字符的同时复制字符串

    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,除了它们加载到 / 存储自al.

于 2015-10-26T22:46:32.580 回答
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
于 2017-12-27T04:51:53.713 回答