jviotti
jviotti

Reputation: 18949

Iterate through string in memory in Assembly

I'm having some troubles accessing each character of a string in turn in Assembly. I have the following code that calls the print_string routine, before declaring 'Hello World!', 0 into the bx registry:

mov bx, HELLO_MSG
call print_string

HELLO_MSG:
  db 'Hello, World!', 0

Within print_string, I'm able to print the first character of the string by doing this:

mov al, [bx]

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

In my basic understanding of assembly, the address of the first character (H) got saved into bx, so by doing mov al, [bx] I'm dereferencing the pointer and assigning the real value of H into al.

Based on that understanding (please correct me if I'm wrong) I've tried the following approaches:

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

But I got this error pointing to the mov al, [cl] line:

error: invalid effective address

I've also tried the following:

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.

Upvotes: 3

Views: 19464

Answers (1)

Gunner
Gunner

Reputation: 5884

Many, many years ago, someone put it this way:
Do you want the box, or what is in the [box]?

I've also tried the following:

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

The CPU is doing exactly what you told it to do!

mov al, [bx]

Moves the value pointed to by bx into al (in your case, H)

add al, 1

adds 1 to H.

add bx, 1
mov al, [bx]

Now, al will contain E

Or you could do:

mov al, [bx + 1]

to get E

In your other code, bx is a word sized register (16 bits) and cl is a byte sized register (8 bits) you truncated the address hence the invalid address (what do you expect to happed when you try to put 16 bits into an 8 bit register?)

Here is an example:

 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

Output:

enter image description here

Upvotes: 10

Related Questions