我使用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?或者我必须使用注册?那我该怎么办?
感谢所有回复。
答案 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的内容。