pra*_*dhe 0 assembly fasm x86-16
我已经完成了我的研究,并偶然发现了许多解决方案来更改字符串的某些字符。我正在尝试以字符串形式打印十六进制代码。但我已经尝试了所有的解决方案,但它不会在“平面汇编器”上编译。以下是我的代码:
mov bx, HELLO
call print_string
mov dx, 0x1fb6
call print_hex
jmp $
print_hex:
pusha
mov cx, HEXi
mov al, byte ptr [cx]
back:
popa
ret
include "print_string.asm"
HELLO: db 'Hello, World!',0
HEXi: db '0x0000',0
times 510 -( $ - $$ ) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)
在编译时它只显示无效的表达式错误。
- FASM 抱怨“用作符号的保留词”
MOV AX、[CX] 或 JMP WORD [AX] 等指令会导致此错误 - FASM 错误?
你的BUG。只有 BX、BP、SI 和 DI 可用于 16 位代码的索引。FASM的报告不好,但源于内部设计。这是8086设计和16位代码的“问题”。使用更多的寄存器(如 EAX 等)进行寻址是 80386 和更高版本 CPU 上 32 位代码的特权。
并非每个寄存器 16 位寄存器都可以用作地址寄存器,仅允许以下组合:
[displacement][BX+displacement][BP+displacement][SI+displacement]或[DI+displacement][BX+SI+displacement]或[BX+DI+displacement][BP+SI+displacement]或[BP+DI+displacement]位移为0时可以省略,例如这里可以是变量名。在这种情况下,你可以写
mov al, [HEXi]
Run Code Online (Sandbox Code Playgroud)
代替或使用允许的寄存器之一:
mov di, HEXi
mov al, [di]
Run Code Online (Sandbox Code Playgroud)
此处不必使用 指定寄存器大小byte,因为它已由目标寄存器明确指定。
如何操作 HEXi 字符串的字符?
假设要输出的值是 indx并且应该写为字符串中的十六进制数HEXi。和
mov [bx+HEXi], al
Run Code Online (Sandbox Code Playgroud)
寄存器中的一个字符al可以写到 的bx第 -th 个位置HEXi,从零开始。由于字符串已经开始0x并且不应被覆盖,因此使用跳过前两个字符
mov [bx+HEXi+2], al
Run Code Online (Sandbox Code Playgroud)
该值HEXi+2被编码为上面提到的立即数。现在应该将 4 位每个都转换为十六进制数字,即字符
0到9(字符代码0x30到0x39)和A到F(字符代码0x41到 0x46`)。这是通过以下步骤完成的:第一的低4位dx被分离并转换成字符代码0x30最多0x3F以
mov al, dl ; Copy the lower 8 bits of dx to al
and al, 0x0F ; Set the upper 4 bits of al to zero
or al, 0x30 ; Convert to charcode
Run Code Online (Sandbox Code Playgroud)
字符代码0x3Ato0x3F必须转移到0x41to 0x46。为此,首先检查值是否在其中,以便在必要时进行移位:
cmp al, 0x39
jbe noShiftNeeded
add al, 7
noShiftNeeded:
Run Code Online (Sandbox Code Playgroud)
这应该发生的所有在16位值的4位半字节dx。在每一步之后,dx右移 4 位,以便可以再次使用之前的代码。那么最终的代码是:
print_hex:
pusha
mov bx, 3 ; Start with last character
hexLoop:
mov al, dl ; Copy the lower 8 bits of dx to al
and al, 0x0F ; Set the upper 4 bits of al to zero
or al, 0x30 ; Convert to charcode
cmp al, 0x39
jbe noShiftNeeded
add al, 7
noShiftNeeded:
mov [bx+HEXi+2], al ; Write the character to HEXi
shr dx, 4 ; To be able to repeat this with the next 4-bit nibble
sub bx, 1 ; If this wasn't the forth character, repeat
jnc hexLoop
popa
ret
Run Code Online (Sandbox Code Playgroud)