MS-DOS 调试器,移动到下一个内存位置
MS-DOS Debugger, move to next memory location
我正在使用 DosBox,并且我使用中断从缓冲区中读入了一个字符串。我知道第一个字符在内存中的存储位置,如何递增到下一个字符?
0100 mov ah, 0a
0102 mov dx, 111
0105 int 21
0107 mov dl, [113] ;first character here
010b mov ah, 02
010d int 21
010f int 20
0111 db 0f
问题是如何递增到字符串中的下一个字符?如果我输入字符串 "Hello" 然后使用 inc dl
它只会给我字母 "I" 而不是 "e".
您需要选择一个寄存器指向当前字符。一旦你有了这个,就会有推进你的指针的指令以及读取指针指向的字节的指令。
由于您不知道用户输入函数将读取多少个字符,并且您希望此函数使用任何输入值,因此您需要某种循环以便只打印尽可能多的字符如前所述,尽管如果你想让它变得简单,你可以让它只打印前 3 个字符,而不管输入的是什么。我假设你想准确地打印出用户输入的内容。
解决这个问题的一个好方法是使用 LOOP 指令,该指令根据已放入 CX 寄存器的计数重复(跳入)循环体。由于用户输入函数为我们提供了字符数,我们所要做的就是将其读入 CX 寄存器 (CL) 的下半部分以进行循环初始化。我们还需要一个指向当前字符的指针。一旦进入循环体,我们将只读取 "current character" 指针处的任何字符,然后调用 DOS 字符打印函数将其输出到控制台。然后我们可以推进指针和循环,直到完成所有字符。请注意,每次遇到 LOOP 指令时,CX 都会递减,直到达到零。一旦它为零,LOOP 就不再跳回主体,而是简单地前进到 LOOP 之后的指令。
注意:如果您在读取用户输入后未输出 CRLF,则不会有换行,新输出将覆盖在控制台上读取输入的位置。实际上它看起来就像什么都没发生过一样。
这是您修改后的示例:
0100 MOV AH,0A
0102 MOV DX,0123
0105 INT 21 ;input string using buffer at 0123
0107 MOV DX,0120
010A MOV AH,09
010C INT 21 ;output CRLF sequence first
010E MOV SI,0124 ;point SI at byte containing chars read
0111 XOR CX,CX ;CX = 0
0113 MOV CL,[SI] ;CX = chars_read
0115 INC SI ;mov SI to next char to display
0116 MOV DL,[SI] ;DL = character SI is pointing at
0118 MOV AH,02
011A INT 21 ;display character
011C LOOP 0115 ;loop back to INC instruction until no more chars left
011E INT 20 ;exit
0120 DB 0D ;CR
0121 DB 0A ;LF
0122 DB 24 ;"$" DOS string terminator
0123 DB 20 ;buffer start; max characters = 32
0124 DB 00 ; chars read goes here
0125 DB 00 ; input chars are read here
我正在使用 DosBox,并且我使用中断从缓冲区中读入了一个字符串。我知道第一个字符在内存中的存储位置,如何递增到下一个字符?
0100 mov ah, 0a
0102 mov dx, 111
0105 int 21
0107 mov dl, [113] ;first character here
010b mov ah, 02
010d int 21
010f int 20
0111 db 0f
问题是如何递增到字符串中的下一个字符?如果我输入字符串 "Hello" 然后使用 inc dl
它只会给我字母 "I" 而不是 "e".
您需要选择一个寄存器指向当前字符。一旦你有了这个,就会有推进你的指针的指令以及读取指针指向的字节的指令。
由于您不知道用户输入函数将读取多少个字符,并且您希望此函数使用任何输入值,因此您需要某种循环以便只打印尽可能多的字符如前所述,尽管如果你想让它变得简单,你可以让它只打印前 3 个字符,而不管输入的是什么。我假设你想准确地打印出用户输入的内容。
解决这个问题的一个好方法是使用 LOOP 指令,该指令根据已放入 CX 寄存器的计数重复(跳入)循环体。由于用户输入函数为我们提供了字符数,我们所要做的就是将其读入 CX 寄存器 (CL) 的下半部分以进行循环初始化。我们还需要一个指向当前字符的指针。一旦进入循环体,我们将只读取 "current character" 指针处的任何字符,然后调用 DOS 字符打印函数将其输出到控制台。然后我们可以推进指针和循环,直到完成所有字符。请注意,每次遇到 LOOP 指令时,CX 都会递减,直到达到零。一旦它为零,LOOP 就不再跳回主体,而是简单地前进到 LOOP 之后的指令。
注意:如果您在读取用户输入后未输出 CRLF,则不会有换行,新输出将覆盖在控制台上读取输入的位置。实际上它看起来就像什么都没发生过一样。
这是您修改后的示例:
0100 MOV AH,0A
0102 MOV DX,0123
0105 INT 21 ;input string using buffer at 0123
0107 MOV DX,0120
010A MOV AH,09
010C INT 21 ;output CRLF sequence first
010E MOV SI,0124 ;point SI at byte containing chars read
0111 XOR CX,CX ;CX = 0
0113 MOV CL,[SI] ;CX = chars_read
0115 INC SI ;mov SI to next char to display
0116 MOV DL,[SI] ;DL = character SI is pointing at
0118 MOV AH,02
011A INT 21 ;display character
011C LOOP 0115 ;loop back to INC instruction until no more chars left
011E INT 20 ;exit
0120 DB 0D ;CR
0121 DB 0A ;LF
0122 DB 24 ;"$" DOS string terminator
0123 DB 20 ;buffer start; max characters = 32
0124 DB 00 ; chars read goes here
0125 DB 00 ; input chars are read here