【问题标题】:How to copy character from one memory location to another in x86 assembly?如何在 x86 程序集中将字符从一个内存位置复制到另一个内存位置?
【发布时间】:2011-11-27 17:57:45
【问题描述】:

我正在尝试使用 16 位汇编复制字符串。

我(除其他外)在 .dirBafer 中有 16 个 11 个字符的字符串,我想将每个字符串复制到 .ime_dat 中,以便稍后打印和处理(处理代码尚未编写) .每个字符串的第一个字符由 32 个字节的数据分隔。基本上 .dirbafer 是 FAT12 目录的转储,我正在尝试打印文件名。

我有以下代码:

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

我的问题是:

mov dx, [ax]产生无效有效地址错误。

我做错了什么,我该如何解决?

【问题讨论】:

    标签: assembly x86 nasm


    【解决方案1】:

    好的,我想通了。看来,对于这样的操作,我需要使用 si 和 di 寄存器而不是 ax 和 bx。它们被适当地命名为源索引和目标索引寄存器。

    【讨论】:

    • 如果您查找系统 ABI 的暂存寄存器可能会有所帮助,因为这些寄存器不会跨调用(通常是 EAX、ECX 和 EDX)保留。
    • @Necrolis 在我的特殊情况下它们是(嗯,我正在使用的)。只是要明确一点:如果不是,我会得到运行时错误,对吗?我在组装过程中遇到了错误。
    • 啊,是的,没关系,这里有点晚了,我没有直接阅读:S 然而,还是看看你系统的 ABI,从长远来看它可能会对你有所帮助:)
    • @Necrolis 我已经阅读了整个系统的源代码大约 20 次。幸运的是,它并没有那么大,可能只有大约 5000 行组装。困扰我的是 NASM 的行为。
    • @Necrolis 在我的情况下归结为操作系统的来源,因为没有书面标准。
    【解决方案2】:

    DX 是一个 2 字节的寄存器。如果您只想访问一个字节,则应使用 DL 寄存器:

    mov dl, [ax]
    mov [bx], dl
    

    【讨论】:

    • 是的,没错,但这个答案对我没有帮助。即使我这样做,我也会遇到同样的错误。尽管如此,你还是会得到 + 的努力。
    • _print_string 是否有可能改变 dx 的值?这似乎是 ax 可以成为无效地址的唯一原因。
    • 不,_print_string 开头是pusha,结尾是popa,它不使用dx。
    • AX 不适合索引寄存器使用。
    猜你喜欢
    • 2017-11-23
    • 2021-02-11
    • 1970-01-01
    • 2019-02-02
    • 2016-03-27
    • 2014-11-25
    • 2019-12-27
    • 2013-05-02
    相关资源
    最近更新 更多