.MODEL SMALL
.STACK 100h
.DATA
men1 db 0dh,0ah," $"
men2 db 0dh,0ah," MAIN MENU$"
men3 db 0dh,0ah," [1]Calculator$"
men4 db 0dh,0ah," [2]Conversion$"
men5 db 0dh,0ah," [3]Exit$"
Run Code Online (Sandbox Code Playgroud)
有没有办法只使用寄存器来显示这个字符串?
如何将字符串存储在寄存器中?是否可以?
不,除非它是 2 个字节或更短。(或者你将它拆分到多个寄存器中。)这就是为什么你通常只存储一个指向它的指针,以及为什么 C 函数像strchr接受一个char*arg:没有办法在寄存器中按值传递任意长度的字符串。
有没有办法只使用寄存器来显示这个字符串?
当然,一次一个字符,使用立即数。(当然,视频 RAM 最终是内存,或者至少在物理地址空间中。您必须从 CPU 寄存器中的某处获取数据,但它不必从数据内存中开始。
当然,如果它在内存中,效率会更高,因此您可以循环遍历它,而不必像这样完全展开
mov ah, 0Eh ; BIOS service number for teletype output, set up once ahead of time
mov al, 'M'
int 10h ; BIOS teletype output
mov al, 'A'
int 10h
...
Run Code Online (Sandbox Code Playgroud)
(该BIOS 调用不会破坏AH.)
mov byte ptr [video_ram], 'M'将是另一种方式,video_ram引用它的段和偏移量的某种组合在哪里。如果您有一个清零寄存器作为基数,并用作段,那么每个字符存储,操作码 + modrm + disp8 + imm8可以让您减少到4 个字节DS。例如
mov bx, vga_base
mov ds, bx
xor bx, bx
mov byte ptr [bx+0], 'M' ; assuming VGA text mode
mov byte ptr [bx+2], 'E' ; where even bytes are chars
mov byte ptr [bx+4], 'N' ; and odd bytes are attributes (e.g. FG/BG colour)
...
mov byte ptr [bx+126], 'x'
add bx, 128
; signed 8-bit displacement only goes up to +127
mov byte ptr [bx+0], 'y'
; you *could* increment by 256, and start with [bx-128] instead of 0.
Run Code Online (Sandbox Code Playgroud)
您也可以使用字存储而不是字节来设置属性。
请注意,这甚至不使用数据寄存器。使用mov byte ptr [0], 'M',我们甚至不会使用寄存器,但是对于寻址模式下的绝对 disp16,每条指令会花费额外的字节。