在汇编中遍历内存中的字符串

3

我在汇编中遇到了一些问题,想要逐个访问字符串中的每个字符。我有以下代码调用print_string例程,在将'Hello World!', 0赋值给bx寄存器之前:

mov bx, HELLO_MSG
call print_string

HELLO_MSG:
  db 'Hello, World!', 0

print_string函数中,我可以通过以下方法打印字符串的第一个字符:
mov al, [bx]

; Trigger a single character print
mov ah, 0x0e
int 0x10

在我对汇编的基本理解中,第一个字符 (H) 的地址被保存到了 bx 中,所以通过执行 mov al, [bx] 我对指针进行了解引用,并将真实值 H 赋给了 al

基于这个理解(如有错误请指出),我尝试了以下方法:

mov cl, bx ; Move the pointer to `cl`
add cl, 1 ; Do pointer arithmetic to add one byte to the address (hopefully referencing the next character)
mov al, [cl] ; Dereference the address

但是我得到了一个错误,指向mov al,[cl]这一行:

error: invalid effective address

我也尝试了以下方法:
mov al, [bx] ; Move the dereferenced address to `al` (so `al` has `H`)
add al, 1 ; Increment `al`, but of course I'm getting the ASCII value of `H` + 1, which is not the next character in the string.
1个回答

10

很久很久以前,有人这样说过:
你想要盒子,还是盒子里的东西?

我也尝试过以下方法:

mov al, [bx] ; Move the dereferenced address to `al` (so `al` has `H`) 
add al, 1 ; Increment `al`, but of course I'm getting the ASCII value of `H` + 1

CPU正在按照您的指令执行任务!

mov al, [bx]

将 bx 指向的值移动到 al 中(在您的情况下为 H)

add al, 1

将H加1。

add bx, 1
mov al, [bx]
现在,al将包含E。
或者你可以这样做:
mov al, [bx + 1]

获取 E

在你的其他代码中,bx 是一个字寄存器(16位),而 cl 是一个字节寄存器(8位)。因为你截断了地址,所以出现了无效地址(当你试图将16位放入8位寄存器中时,你期望会发生什么?)

这是一个例子:

 HELLO_MSG db 'Hello, World!', 0
 HELLO_LEN equ  $ - HELLO_MSG
...
...
...
    mov     si, HELLO_MSG
    xor     bx, bx
Next:
    mov     al, byte [si + bx]
    mov     ah, 0x0e
    int     0x10

    mov     al, 10
    mov     ah, 0x0e
    int     0x10

    inc     bx
    cmp     bx, HELLO_LEN
    jne     Next

输出:

输入图像描述


感谢您的全面解释!在此之后,我清楚地知道如何解决问题了。 - jviotti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接