MIPS Assembly - String (ASCII) Instructions
我正在用C编写用于MIPS汇编的汇编程序(因此它将MIPS汇编转换为机器代码)。
现在,MIPS具有三种不同的指令:R型,I型和J型。但是,在.data中。部分,我们可能会有类似message: .asciiz"hello world"的内容。在这种情况下,我们如何将ASCII字符串转换为MIPS的机器代码?
谢谢
ASCII文本不会转换为机器代码。它通过Wikipedia上的格式存储。
MIPS使用此格式存储ASCII字符串。特别是对于.asciiz,它是字符串加上NUL字符。因此,根据工作表,A在十六进制中为41,而在二进制中仅为0100 0001。但是请不要忘记NUL字符,因此:0100 0001 0000。
在存储字符串时,我会采用Mars MIPS模拟器的想法,只需在内存中的已知地址处启动内存部分,然后对设置为内存中该位置的标签message进行任何引用。
请注意,数据部分中的所有内容都不是R型,I型或J型。这只是原始数据。
-
并假设输入字符集也是ASCII(或者可能是UTF-8),则汇编程序应该简单地将字节从源复制到输出文件(在当前输出位置),直到引用字符串的末尾。尽管确实需要处理C型转义序列,例如\
= 0xa(LF =换行符)。
正如其他答案所指出的,.ascii"string"指令中包含的ascii以其原始二进制格式编码在目标文件的数据段中。至于从那里发生的情况,这取决于汇编器编码成的二进制格式。通常,数据不编码为机器代码,但是GNU as会很高兴地将其汇编为:
1 2 3 4 5
| .text
start:
.ascii"Hello, world"
addi $t1, $zero, 0x1
end: |
如果您在objdump中反汇编输出(我在这里使用mips-img-elf工具链),则会看到以下内容:
1 2 3 4 5 6 7
| Disassembly of section .text:
00000000 <message>:
0: 48656c6c 0x48656c6c
4: 6f2c2077 0x6f2c2077
8: 6f726c64 0x6f726c64
c: 20090001 addi t1,zero,1 |
十六进制序列48 65 6c 6c 6f 2c 20 77 6f 72 6c 64拼写为" Hello,world"。
我来到这里的时候是在寻找关于GAS为何如此行为的答案。火星将不会汇编上述程序,并给出一个错误,即数据指令不能在文本段中使用
有人在这里有见识吗?
-
洞悉什么?为什么MARS的汇编器上有训练轮,而又不允许您在asm源要求它们的地方汇编任意字节?通常,您会将字符串放在.section .rodata中,在此将它们作为文本段的一部分进行链接,但是将它们放在不会执行的文本段中是完全可以的。或使用.byte 0x20, 0x09, 0x00, 0x01或其他内容手动编码指令。 (通常没有理由这样做,但是您可以根据需要这样做。)
-
但是,如果您不了解自己在做什么,就很容易将数据放在执行将落入其中的位置,这对于初学者可能会造成混淆,因此在MARS中使用了训练轮/神经节填充。我认为它的仿真器/仿真器确实可以从MIPS机器代码运行您的程序,因此,我不认为MARS直接"组装"到仿真器内部,并且将.text部分限制为只能从文本中解析的asm指令。
-
嗨,彼得,谢谢您的回复。我在这里不关心MARS的行为,我对为什么GAS允许您使用.ascii指令将原始字节编码到.text部分中感兴趣。我认为您已经回答了这个问题,尽管您可以使用这些指令在任意位置放置任意二进制数据,这可能用于手动编码指令。我再次看了看,是的,objdump将尝试使用这些指令将您插入的二进制数据解释为指令。
-
是的,objdump无法确定字节是如何到达那里的。这些全都是汇编程序输出文件中的字节。火星绝对是例外。大多数汇编程序就像GAS一样,无论当前段是什么,都会很高兴地将一行asm源代码汇编为字节。程序员有责任确保它有用。
-
感谢您清理此问题。这种看待事物的方式非常有意义,并解释了GAS为何允许这样做。
数据不可执行,因此不应转换为机器代码。应该以目标数据类型的正确二进制表示形式对其进行编码。
- 是的,我知道这一点。我的.data只能有.word或.asciiz。如果它是.word,那么我只是将数字转换为其32位表示形式。但是,您如何将.asciiz表示为机器代码指令?我需要将其转换为机器代码。因此,array: .word 0:10将为此创建10条指令:000000000000000000000000000001010
-
.asciiz不是机器代码指令,它是汇编程序指令。它告诉汇编程序应将这种数据以某种格式存储在最终的二进制文件中。换句话说,汇编程序负责将您的数据表示形式转换为正确的二进制格式,并将其存储在可执行文件中。
-
您不会将.asciiz表示为机器代码指令。假设您要实现一个相当标准的ABI,则将其存储为一个字节序列,每个字节包含一个字母的ASCII值,后跟一个NUL终止符。
-
对啊很抱歉使用"机器代码指令"。我的意思是"字节序列"。谢谢你。