我不知道86 ASM非常好,但我宁愿舒服SHARP-Z80,我知道的每个指令(助记符)具有相应的字节/字价值体验,并通过查看组装的十六进制转储二进制文件,我可以“回读”相同的代码,我写了使用助记符。
在另一个SO问题 ,有人声称 , 在哪里ASM指令不翻译成其相应的二进制值,而是在由汇编以不同的方式重新排列的一些情况 。
我在寻找尤其是对情况拆卸二进制将导致比原来的一个不同的ASM代码。
换句话说, 是否有任何情况下,汇编代码不为1:1的比例与组装代码?
MikeKwan链接到另外一个问题,如果GCC会修改内联汇编代码(在C项目),但是,即使这是一个有趣的话题,它并没有回答这个问题,因为GCC是一个编译器,并总是试图优化代码和内嵌ASM trnslation由围绕C代码的影响。
为了汇编程序设计师认为这是有帮助的程度,它可能会用具有其他有用的特性等效指令。
首先,有机具有可变长度的值的操作数的字段。 如果值/偏移将适用于任何几个变种,它是常见的汇编替代最短。 (在这样的装配中,也常见于能够力的特定大小)。 这是,涉及立即数和索引寻址指令的正确。
许多机器与PC相关的偏移量的指令,通常为的JMP,有时加载/存储/算术指令。 在第一遍期间遇到这样的指令可确定所寻址的操作数的汇编程序先于insruction或它未见指令尚未。 如果前面,汇编器可以选择相对短形式或长相对形式,因为它知道偏移。 如果以下,汇编器不知道大小,并且通常会选择大的,它PASS2期间填补了指令的偏移量。 同样,也往往是如何迫使汇编程序选择短形式。
一些机器不具有跳远相关说明。 在这种情况下,如果目标先于JMP和是由靠近汇编器将向后插入一个相对短JMP。 如果目标先于但远离,或目标是一个前向参考,汇编器可以插入在相对分支条件与目标是过去的下一个指令的短相对JMP,接着是长的绝对JMP。 (我个人建造装配这样的)。 这确保了JMPS总能得到他们的目标。
关于这些技巧的好消息是,如果你拆开,你仍然可以得到一个有效的汇编程序。
现在让我们谈谈那些会迷惑你的反汇编。
类似的特技跳如果机器具有短相对寻址用于加载/存储指令和编程明显指定一个很远的恒定或值的负载,可以使用相对于字面的操作数。 在这种情况下汇编改变instuction指文字或一个地址常量以下围绕该恒定插入的短相对JMP。 该伪君子认为一切指令流中是一个指令; 在这种情况下,文本值是不是和这将引发反汇编了。 至少还有周围的文字无条件JMP指导反汇编。
Screwier技巧你会发现在每一个想象的特技支持成熟的装配。 我的一个在8个装配最喜欢的是“伪” instuctions SKIP1,SKIP2,你可以认为是极短的相对分支。 他们真的只是“CMP#8位”和“CMP#16位”指令opcoode字节,并用于跳来跳去分别为8位或16位的指令。 所以,“一个字节的”相对的跳跃,而不是两个。 当你挤压空间,每一个字节计数: - {
SKIP1
INC ; 8 bit instruction
...
这也是试图执行一些地方的步骤不应该在循环条目进行循环时得心应手,但需要进一步的循环迭代完成:
SKIP2
LOOP: SHLD ; 16 bit instruction
...
BNE LOOP
这里这个问题,如果你拆开SKIP1或SKIP2指令,你将不会看到INC(或相应的16位指令)。
传递参数使用汇编语言程序员技巧是内嵌在他们的电话后,与被调用的例程适当调整寄信人地址的条件:
CALL foo
DC param1
DC param2
或CALL PRINTSTRING DC“的可变长度的字符串”,0
没有实际的方式,反汇编可以知道正在使用这样的公约或该公约是什么,所以伪君子势必处理这个错误。
文章来源: Can assembled ASM code result in more than a single possible way (except for offset values)?