assembly - 如何在程序集中更新字符串的字符?
问题描述
我已经完成了研究,并偶然发现了许多更改字符串某些字符的解决方案。我正在尝试以字符串形式打印十六进制代码。但我已经尝试了所有解决方案,但它不会在“平面汇编器”上编译。以下是我的代码:
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
在编译时它只显示无效的表达式错误。
解决方案
从平面组装板:
- 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]
代替或使用允许的寄存器之一代替:
mov di, HEXi
mov al, [di]
寄存器大小不必在此处用 指定byte
,因为它由目标寄存器明确指定。
如何操作 HEXi 字符串的字符?
假设要输出的值dx
在字符串中并且应该写为十六进制数HEXi
。和
mov [bx+HEXi], al
可以将寄存器中的一个字符al
写入 的bx
第 - 个位置HEXi
,从零开始。由于字符串已经以开头0x
并且不应被覆盖,因此使用跳过前两个字符
mov [bx+HEXi+2], al
该值HEXi+2
被编码为上面提到的立即值。现在 4 位应分别转换为十六进制数字,即字符
0
to9
(字符代码0x30
to0x39
)和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
字符代码0x3A
to0x3F
必须转移到0x41
to 0x46
。为此,首先检查值是否在其中,以便在必要时对其进行移位:
cmp al, 0x39
jbe noShiftNeeded
add al, 7
noShiftNeeded:
这应该发生在所有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
推荐阅读
- sql - 如何在每个新成立的组中对聚合进行排名?
- android - 为什么使用协程延迟()进行单元测试会失败?
- django - django-rest 在调用 http 删除时返回 http 301 状态码而没有斜杠
- python - 在 argparse 中存在位置参数的情况下,如何通过 = 正确传递可选参数?
- python-3.x - 无法使用 Scrapy 执行登录以进行抓取
- jquery - Shopify 主题开发 - jQuery 无法找到同级子元素
- python - 在 Python 中将图像中的颜色映射到颜色列表中最接近的成员
- postgresql - 为postgres中不存在的表创建外键
- python - 多类分类中每个类的特征重要性
- scala - Avro Schema:从 Schema 字段构建 Avro Schema