我正在尝试获取字符串的第二个字符(例如e
中的Test
)。使用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
我得到♦
。
当我将第二个片段的“获取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
呢?串?还是我误导的方法?
答案 0 :(得分:0)
str[si]
不是某种类型/数组访问,但是它将转换为指令存储器操作数,例如[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实模式访问内存,等等...