程序集mov与位置存储在变量中

时间:2014-10-27 21:00:46

标签: assembly nasm intel

我使用nasm作为英特尔处理器,只是为了告诉你我的情况。

所以这是我的问题:

我有一个名为pos的变量,它应该存储像3998这样的内存地址。现在我想转移到此var中存储的地址。我该怎么做呢?它甚至可能吗?

现在就是我的代码:

mov ax, 0xb800 ; Go to the adress of the video card
mov ds, ax

printloop:
    cmp [pos], byte 0 ; check if the value stored in pos is not  0
    je hang
    mov [pos], byte 36 ; PROBLEM: what it should do: write the ascii symbol(here $) to the position stored in pos
    sub [pos], byte 2 ; decrement address stored in pos by two
    jmp printloop

hang: ; just a hang loop when all is done
    jmp hang

pos db 3998 ; the var pos with the initialization address 3998, which is the down right corner

是否可以使用var?或者我必须使用注册?那我该怎么办?

感谢所有回复。

2 个答案:

答案 0 :(得分:0)

看起来你想要做的是通过寄存器使用间接寻址:

mov bx, [pos]
mov byte [bx], 36

您还需要使用dw代替db来定义pos,因为3998对于单个字节而言值太大。

答案 1 :(得分:0)

一个问题是,如果我们处于实模式或v86模式,则段大小限制为64 KB,因此我们不能使用相同的DS段地址来寻址pos的位置在framebuffer之外的标签,以及另一个位于帧缓冲区内的另一个位置。

一种解决方案是使用第二个段寄存器,一个段寄存器用于寻址帧缓冲区,另一个用于寻址pos标签的位置。 (@Frank Kotler:我总是想注意你的专业知识。)

mov ax, 0xb800 ; segment address of the framebuffer
mov es, ax     ; store it into the ES segment register

; not shown here,but with a DOS *.exe file we default use a separated DATA-segment
; DS=CS if the label of pos is placed inside of our codesegment
; (not needed if running as a DOS *.COM file)
mov ax, cs     ; get the segment address of the code segment
mov ds, ax     ; store it into the DS segment register

printloop:
cmp [pos], byte 0 ; check if the value stored in DS:pos is not  0
je hang
mov di, [pos]     ; get the offset address stored in DS:pos
mov es:[di], byte 36 ; write the ascii symbol to the position stored in es:di
sub [pos], byte 2 ; decrement address stored in DS:pos by two
jmp printloop

hang: ; just a hang loop when all is done
jmp hang

pos dw 3998 ; the (16 bit) offset address 3998, which is the down right corner

也可以将指令放在循环上方(仅需要该指令一次)并减少DI寄存器并比较循环内的DI寄存器而代之以减少并检查pos的内容。