如何在 Assembly 中更新字符串的字符?

How to update character of string in Assembly?

我进行了研究,偶然发现了许多更改字符串中某些字符的解决方案。我正在尝试以字符串形式打印十六进制代码。但我已经尝试了所有的解决方案,但它不会在“Flat assembler”上编译。以下是我的代码:

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

在编译时它只是显示无效表达式错误。

来自flatassembler board

  1. FASM whines with "reserved word used as symbol"

Instructions like MOV AX, [CX] or JMP WORD [AX] cause this error - FASM bug ?

Your BUG. Only BX, BP, SI and DI are available for indexing in 16-bit code. FASM's report is bad, but it originates from internal design. This is a "problem" of 8086 design and 16-bit code. Using more registers like EAX etc. for addressing is a privilege of 32-bit code on 80386 and later CPU's.

不是每个寄存器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 中的一个字符可以从零开始写入 HEXi 的第 bx 位置。由于字符串已经以 0x 开头并且不应被覆盖,因此使用

跳过前两个字符
  mov [bx+HEXi+2], al

HEXi+2被编码为上面提到的立即数。现在应该将 4 位分别转换为十六进制数字,即字符

  • 09(字符代码0x300x39)和
  • AF(字符代码 0x41 到 0x46`)。 这是通过以下步骤完成的:

首先将dx的低4位分离出来,转换成字符码0x300x3F

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

字符代码0x3A0x3F必须转换为0x410x46。为此,首先检查值是否在其中,以便在必要时移动它:

    cmp  al, 0x39
    jbe  noShiftNeeded
    add  al, 7
noShiftNeeded:

dx 中 16 位值的所有 4 位半字节都应该发生这种情况。每一步后,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