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
...
Вы должны использовать некоторый отладчик и наблюдать значения в памяти, а также регистры и собранные инструкции, чтобы лучше понять, как они работают внутри ЦП, как сегментная адресация используется для доступа к памяти в реальном режиме 16b x86, и т.д ...