为什么我在获取和显示字符串中的字符时会得到意想不到的结果?
Why am I getting unexpected results when getting and displaying a character from a string?
我正在尝试获取字符串的第二个字符(例如 Test
中的 e
)。使用emu8086编译。
当我这样做时:
str db 'Test$'
...
mov si, 1 ; get second character of str
mov bl, str[si] ; store the second character
mov ah, 2 ; display the stored character
mov dl, bl
int 21h
输出为e
。
但是当我这样做时:
str db 25
db ?
db 25 dup (?)
...
mov ah, 0ah ; accept a string
lea dx, str ; store input in variable str
int 21h
mov si, 1 ; get second character of str (??)
mov bl, str[si] ; store the second character
mov ah, 2 ; display the stored character
mov dl, bl
int 21h
我得到 ♦
。
当我将第二个片段的 "get second character of str" 部分更改为:
mov si, 3 ; get second character of str (why is it '3' instead of '1'?)
mov bl, str[si] ; store the second character
我得到 e
。
我不明白。虽然它在第一个代码段中有效,但为什么在第二个代码段中,我将 SI
设置为 3
而不是 1
,如果我试图引用细绳?还是我使用的方法被误导了?
str[si]
不是某种type/array访问,但它会像[si+1234]
一样翻译成指令内存操作数,其中“1234”是偏移量,其中标签str
指向内存中。
在你的第二个例子中,str
标签指向值为 25 的字节(缓冲区的最大长度),然后 str+1
指向返回的输入长度字节(即 ♦
如果您尝试将其作为字符打印出来,则您在输出中获得的值),并且 str+2
指向用户输入的第一个字符。因此,要获得第二个字符,您必须使用 str+3
内存地址。
内存可按字节寻址,因此您要么必须了解所有元素的字节大小,要么使用更多标签,例如:
str_int_0a: ; label to the beginning of structure for "0a" DOS service
db 25
db ?
str: ; label to the beginning of raw input buffer (first char)
db 25 dup (?)
然后在代码中根据您要执行的操作使用正确的标签:
...
mov ah, 0ah ; accept a string
lea dx, str_int_0a ; store input in memory at address str
int 21h
mov si, 1 ; index of second character of str
mov bl, str[si] ; load the second character
mov ah, 2 ; display the stored character
mov dl, bl
int 21h
...
您应该使用一些调试器并观察内存、寄存器和汇编指令中的值,以更好地了解这些在 CPU 中的工作方式,segment:offset 寻址如何用于访问x86 的 16b 实模式内存等...
我正在尝试获取字符串的第二个字符(例如 Test
中的 e
)。使用emu8086编译。
当我这样做时:
str db 'Test$'
...
mov si, 1 ; get second character of str
mov bl, str[si] ; store the second character
mov ah, 2 ; display the stored character
mov dl, bl
int 21h
输出为e
。
但是当我这样做时:
str db 25
db ?
db 25 dup (?)
...
mov ah, 0ah ; accept a string
lea dx, str ; store input in variable str
int 21h
mov si, 1 ; get second character of str (??)
mov bl, str[si] ; store the second character
mov ah, 2 ; display the stored character
mov dl, bl
int 21h
我得到 ♦
。
当我将第二个片段的 "get second character of str" 部分更改为:
mov si, 3 ; get second character of str (why is it '3' instead of '1'?)
mov bl, str[si] ; store the second character
我得到 e
。
我不明白。虽然它在第一个代码段中有效,但为什么在第二个代码段中,我将 SI
设置为 3
而不是 1
,如果我试图引用细绳?还是我使用的方法被误导了?
str[si]
不是某种type/array访问,但它会像[si+1234]
一样翻译成指令内存操作数,其中“1234”是偏移量,其中标签str
指向内存中。
在你的第二个例子中,str
标签指向值为 25 的字节(缓冲区的最大长度),然后 str+1
指向返回的输入长度字节(即 ♦
如果您尝试将其作为字符打印出来,则您在输出中获得的值),并且 str+2
指向用户输入的第一个字符。因此,要获得第二个字符,您必须使用 str+3
内存地址。
内存可按字节寻址,因此您要么必须了解所有元素的字节大小,要么使用更多标签,例如:
str_int_0a: ; label to the beginning of structure for "0a" DOS service
db 25
db ?
str: ; label to the beginning of raw input buffer (first char)
db 25 dup (?)
然后在代码中根据您要执行的操作使用正确的标签:
...
mov ah, 0ah ; accept a string
lea dx, str_int_0a ; store input in memory at address str
int 21h
mov si, 1 ; index of second character of str
mov bl, str[si] ; load the second character
mov ah, 2 ; display the stored character
mov dl, bl
int 21h
...
您应该使用一些调试器并观察内存、寄存器和汇编指令中的值,以更好地了解这些在 CPU 中的工作方式,segment:offset 寻址如何用于访问x86 的 16b 实模式内存等...