3

I'm trying to copy a string using 16-bit assembly.

I have (among other things) 16 11-character strings in .dirBafer and I want to copy each string into the .ime_dat so that I can print it and process it later on (the processing code isn't yet written). The first character of each string is separated by 32 bytes of data. Basically the .dirbafer is a dump of a FAT12 directory and I'm trying to print file names.

I've got following code:

mov dx, .dirBafer ;loads address of .dirBafer in dx
mov cx, 16 ;16 entries in a dir
.load_dir:

            push cx
            mov ax, dx ;loads address of .dirBafer from dx into ax
            mov bx, .ime_dat ;buffer for storing file names
            mov cx, 11 ;each file name is 11 characters long
.ime_dat_str:
            push dx ; push dx, since it's being used as a temporary register
            mov dx, [ax] ;this is supposed to load first char from location pointed byax to dx
            mov [bx], dx ;this is supposed to load the first char from  location pointed by dx to bx

            add ax, 1 ; moving on to the next character
            add bx, 1 ;moving on to the next character

            pop dx ; we pop the dx so that the original value returns
            loop .ime_dat_str ;this should loop for every character in the file name


            mov si, bx ;preparing to print the file name
            call _print_string ; printing the name
            add dx, 32 ; we move to the next dir entry
            pop cx ; popping cx so that the outer look counter can be updated
            loop .load_dir

.dirBafer   times 512 db 0
.ime_dat    times 12 db 0

My problem is that the line:

mov dx, [ax] generates the invalid effective address error.

What am I doing wrong and how do I fix that?

AndrejaKo
  • 1,721
  • 5
  • 25
  • 41

2 Answers2

4

OK, I figured it out. It seems that for such operations, I need to use si and di registers instead of ax and bx. They are appropriately named source index and destination index registers.

AndrejaKo
  • 1,721
  • 5
  • 25
  • 41
  • it might help if you look up the scratch registers for your systems ABI, as these registers are not preserved across calls (generally EAX, ECX & EDX). – Necrolis Nov 27 '11 at 20:03
  • @Necrolis In my particular case they are (well, the ones I'm using). Just to be clear: If they aren't, I'd get runtime error, right? I'm getting error during assembly process itself. – AndrejaKo Nov 27 '11 at 20:38
  • ah, yeah nevermind, bit late here and I'm not reading straight :S however, still take a look at the ABI for your system, it'll probably help you in the long run :) – Necrolis Nov 27 '11 at 20:48
  • @Necrolis I've already read the source for the whole system like 20 times or so. Fortunately it's not that big, maybe just ~5000 lines in assembly. It's the behavior o NASM that's bugging me. – AndrejaKo Nov 27 '11 at 20:52
  • ABI is not the source of the application, its the standard that defines your assembly conventions etc. – Necrolis Nov 28 '11 at 07:07
  • 1
    @Necrolis Which in my case boils down to the source of the OS, since there isn't a written standard. – AndrejaKo Nov 28 '11 at 19:32
3

DX is a 2-byte register. You should use DL register instead if you only want to access one byte:

mov dl, [ax]
mov [bx], dl
extesy
  • 93
  • 1
  • 5