写入字符串 16 位 fasm 汇编
Write string 16-bit fasm assembly
我制作了应该与 vmem 一起工作的驱动程序,但它不起作用。我认为错误是我用来指向内存的寄存器。
有驱动代码:
;;;;;;; Primary Video Driver
PVideo:
.treadbyte: ; in:eax=ID, [0 - 3440]; out:cl=BYTE [0 - 255]
push eax ebx
mov ebx, 0xb8000
imul eax, 2
inc eax
add ebx, eax
mov cl, byte[ebx]
pop eax ebx di
ret
.treadattr: ; in:eax=ID, [0 - 3440]; out:cl=BYTE [0 - 255]
push eax ebx
mov ebx, 0xb8000
imul eax, 2
add ebx, eax
mov cl, byte[ebx]
pop eax ebx
ret
.twritebyte: ; in:eax=ID, [0 - 3440]/dl=BYTE, [0 - 255]; out:none
push eax ebx
mov ebx, 0xb8000
imul eax, 2
inc ax
add ebx, eax
mov byte[ebx], dl
pop eax ebx
ret
.twriteattr: ; in:eax=ID, [0 - 3440]/dl=BYTE, [0 - 255]; out:none
push eax ebx
mov ebx, 0xb8000
imul eax, 2
add ebx, eax
mov byte[ebx], dl
pop eax ebx
ret
.twritezs: ; in:eax=POS, [0 - 3440-len(ZS)]/si=ZS, offset[0 - 32512]/dl=BYTE; out:none
push eax ebx
mov ebx, 0xb8000
;imul eax, 2
;inc eax
add ebx, eax
.l:
lodsb
cmp al, 0x00
je .ret
mov byte[ebx], dl
inc ebx
mov byte[ebx], al
inc ebx
jmp .l
.ret:
pop eax ebx
ret
我正在分析代码,但找不到任何错误。
P.S.: 我只测试了 .twritezs 函数,也许另一个也不起作用。
这些是代码片段中的错误之处:
- 你在堆栈上
push
的所有东西都需要以相反的顺序出现(如果使用 pop
)。
- 在0x000B8000处的视频内存中,字符代码(ASCII)进入偶地址的字节,颜色代码(属性)进入奇地址的字节。
push eax ebx
lea ebx, [0x000B8000 + eax]
mov ah, dl ; Attribute
.next:
lodsb ; ASCII
cmp al, 0
je .ret
mov [ebx], ax ; Store ASCII at even address and Attribute at next odd address
add ebx, 2
jmp .next
.ret:
pop ebx eax
ret
如果将 ASCII(在偶地址)和属性(在下一个奇地址)一起存储在一条指令中,您可以更快地获得 .twritezs 代码。
请注意 (E)SI
已修改。你没有 push
它。
不清楚为什么要乘以 2,即其他代码片段中 EAX
中的值。 EAX
不是已经在视频缓冲区中准备好使用的偏移量,就像在 .twritezs 代码中一样吗?
我制作了应该与 vmem 一起工作的驱动程序,但它不起作用。我认为错误是我用来指向内存的寄存器。
有驱动代码:
;;;;;;; Primary Video Driver
PVideo:
.treadbyte: ; in:eax=ID, [0 - 3440]; out:cl=BYTE [0 - 255]
push eax ebx
mov ebx, 0xb8000
imul eax, 2
inc eax
add ebx, eax
mov cl, byte[ebx]
pop eax ebx di
ret
.treadattr: ; in:eax=ID, [0 - 3440]; out:cl=BYTE [0 - 255]
push eax ebx
mov ebx, 0xb8000
imul eax, 2
add ebx, eax
mov cl, byte[ebx]
pop eax ebx
ret
.twritebyte: ; in:eax=ID, [0 - 3440]/dl=BYTE, [0 - 255]; out:none
push eax ebx
mov ebx, 0xb8000
imul eax, 2
inc ax
add ebx, eax
mov byte[ebx], dl
pop eax ebx
ret
.twriteattr: ; in:eax=ID, [0 - 3440]/dl=BYTE, [0 - 255]; out:none
push eax ebx
mov ebx, 0xb8000
imul eax, 2
add ebx, eax
mov byte[ebx], dl
pop eax ebx
ret
.twritezs: ; in:eax=POS, [0 - 3440-len(ZS)]/si=ZS, offset[0 - 32512]/dl=BYTE; out:none
push eax ebx
mov ebx, 0xb8000
;imul eax, 2
;inc eax
add ebx, eax
.l:
lodsb
cmp al, 0x00
je .ret
mov byte[ebx], dl
inc ebx
mov byte[ebx], al
inc ebx
jmp .l
.ret:
pop eax ebx
ret
我正在分析代码,但找不到任何错误。
P.S.: 我只测试了 .twritezs 函数,也许另一个也不起作用。
这些是代码片段中的错误之处:
- 你在堆栈上
push
的所有东西都需要以相反的顺序出现(如果使用pop
)。 - 在0x000B8000处的视频内存中,字符代码(ASCII)进入偶地址的字节,颜色代码(属性)进入奇地址的字节。
push eax ebx
lea ebx, [0x000B8000 + eax]
mov ah, dl ; Attribute
.next:
lodsb ; ASCII
cmp al, 0
je .ret
mov [ebx], ax ; Store ASCII at even address and Attribute at next odd address
add ebx, 2
jmp .next
.ret:
pop ebx eax
ret
如果将 ASCII(在偶地址)和属性(在下一个奇地址)一起存储在一条指令中,您可以更快地获得 .twritezs 代码。
请注意 (E)SI
已修改。你没有 push
它。
不清楚为什么要乘以 2,即其他代码片段中 EAX
中的值。 EAX
不是已经在视频缓冲区中准备好使用的偏移量,就像在 .twritezs 代码中一样吗?