Move character from a string to a register in Assembly

Rubiks picture Rubiks · Nov 11, 2017 · Viewed 8.7k times · Source

I am using dosBox and nasm to run this program. I am trying to write an assembly program that takes a user inputted string, then takes each character from that string and puts it into a register. I thought doing mov byte al, msg2 would do the trick. However, I receive an error, obj output driver does not support one-byte relocations". How do I take one character at a time from a string and store it into a register?

%include "io.mac"
.STACK 100H 
.DATA
   msg1  db "Please enter your name",0
   msg2   TIMES 10 Db 0

   .CODE
        .STARTUP

    PutStr msg1  ; print msg1 on the output
    nwln
    GetStr  msg2    ; input string into first space in table
    nwln
    PutStr msg2 ; output string in register table
    mov byte al, msg2


    PutStr ax
    done:                        
        .EXIT

Answer

Sep Roland picture Sep Roland · Nov 12, 2017

The instruction mov al, msg2 would have gotten you the first byte of the string if this were MASM, but since you're using NASM you need to write the square brackets whenever you want to address memory.

mov al, [msg2]

When you wrote mov byte al, msg2, you asked NASM to put the address of msg2 in the AL register which is nearly always wrong since an offset address is supposed to be 16-bit! This is why you received the error:

obj output driver does not support one-byte relocations


Since your aim seems to be to get, one after the other, each character of the string, an instruction that just gets the first character can't help you very much. You need to put the address of the string in a register, read the memory where that register points at, and then increment the register. After doing something useful with AL, you test if the register points behind the last character of the string and if it doesn't you jump back to read the next character.

    mov     bx, msg2
Next:
    mov     al, [bx]
    inc     bx
    ...
    cmp     bx, msg2 + 10   ;Only if msg2 has precisely 10 characters
    jb      Next

A loop like this can only work if whatever code you replace the ... with, doesn't clobber the loop control register BX. If need be you can preserve BX yourself by adding push and pop instructions:

    mov     bx, msg2
Next:
    mov     al, [bx]
    inc     bx
    push    bx
    ...
    pop     bx
    cmp     bx, msg2 + 10   ;Only if msg2 has precisely 10 characters
    jb      Next