【问题标题】:Why am I getting unexpected results when getting and displaying a character from a string?为什么在获取和显示字符串中的字符时会得到意外结果?
【发布时间】:2018-09-03 09:50:15
【问题描述】:

我正在尝试获取字符串的第二个字符(例如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

我收到

当我将第二个 sn-p 的“获取 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

我不明白。虽然它在第一个 sn-p 中有效,但如果我试图引用字符串的第二个字符,为什么在第二个 sn-p 中我将 SI 设置为 3 而不是 1?还是我使用的方法被误导了?

【问题讨论】:

  • str db 25db ?db 25 dup (?)做什么?
  • @Ivan 至少我是怎么理解的,这些行是为了满足调用服务0ah 接受字符串并将其存储在str 中的要求。 str db 25 定义允许输入的最大字符数(这里是 25),db ? 是用户输入的字符数(定义为未知),db 25 dup (?) 存储接受为输入的字符(定义为 25 个未知字符)。 stackoverflow.com/a/29517960/8919391
  • 我认为您应该查看spike.scu.edu.au/~barry/interrupts.html#ah0a 了解详细信息。您可能会在那里找到答案。
  • 该结构的第二个字节在某些 DOS 版本上也是“输入”参数,告诉 DOS 原始缓冲区中有多少字节实际上对“调用输入”有效,所以不是 db ? 它使用db 0 让 DOS 知道当前缓冲区是完全未定义的保留内存更安全。但是所有示例都使用“db?”是很常见的。对于那个 0A 结构中的第二个值,所以不用担心,它无论如何都会组装为db 0。这是 JFYI 评论,也试图让您了解细微的细节如何影响 asm 代码的功能,以及您必须做到的精确程度......

标签: string assembly character x86-16 emu8086


【解决方案1】:

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 中的工作方式,以及在 x86 的 16b 实模式下如何使用段:偏移寻址来访问内存,等等……

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-27
    • 2017-11-23
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    相关资源
    最近更新 更多