【发布时间】:2021-11-06 03:38:51
【问题描述】:
在开发我的汇编程序时,我遇到了一个问题。在汇编语言中,我们可以定义数据值(例如msg db 'Hi')并将该数据的地址粘贴到任何地方,甚至在该数据上方。然而,当汇编代码时,汇编器不知道数据的地址,直到没有处理这些数据的行。
当然,汇编器可以记住我们使用已定义数据地址的机器代码地址,并在处理代码后将记住的地址中的值替换为我们的数据地址。但是,如果我们在 2 字节地址中定义数据(例如在 01 F1),汇编程序会将记忆地址中的 1 个字节替换为地址(01 F1)的 2 个字节,因此立即字段大小将被更改(imm8 -> imm16)和汇编程序应在同一地址重写指令(更改操作码处的 w 和 s 位,并可能设置前缀 0x66)。如果汇编程序将设置前缀 0x66 并且我们的数据定义在该指令之后,则应重写立即字段字节(增加地址值)。
此算法的说明:
以下代码:
mov dh, 09h
add dx, msg
;...
msg db 'Hello$'
将按照以下原则组装:
- 准备代码:
Comment : |===> Remember address of this byte (0x0004)
Comment : | ADD DX,MSG |
Address : 0000 0001 |0002 0003 0004| ... 01F1 01F2 01F3 01F4 01F5 01F6
Code : B4 09 | 83 C2 00 | ... 48 65 6C 6C 6F 24
Comment : ---------------- H e l l o $
- 在记住的地址中重写代码:
Comment : |=============|-This address (msg)
Comment : | ADD DX,01F1 | v
Address : 0000 0001 |0002 0003 0004 0005| ... 01F2 01F3 01F4 01F5 01F6 01F7
Code : B4 09 | 83 C2 F1 01 | ... 48 65 6C 6C 6F 24
Comment : --------------------- H e l l o $
- 重写指令的操作码
83h -> 81h(10000011b -> 10000001b:位s=0):
Comment : |=============|-This address (msg)
Comment : | ADD DX,01F1 | v
Address : 0000 0001 |0002 0003 0004 0005| ... 01F2 01F3 01F4 01F5 01F6 01F7
Code : B4 09 | 81 C2 F1 01 | ... 48 65 6C 6C 6F 24
Comment : --------------------- H e l l o $
- 将数据的新地址 (
0x01F2) 写入立即字段:
Comment : |=============|-This address (msg)
Comment : | ADD DX,01F2 | v
Address : 0000 0001 |0002 0003 0004 0005| ... 01F2 01F3 01F4 01F5 01F6 01F7
Code : B4 09 | 81 C2 F2 01 | ... 48 65 6C 6C 6F 24
Comment : --------------------- H e l l o $
我认为这个算法很难。可以简化吗?
【问题讨论】:
标签: algorithm assembly x86 machine-code