在IT技术领域,是否有必要使用纯二进制代码编写程序?

14

ASM是否存在不够底层的情况?毕竟,汇编语言仍需要汇编有没有人曾经直接使用二进制编写程序呢?我只是想知道,是否存在理论上的原因使这样做变得实用,或者即使在现代计算机上也可能如此。


1
也许你应该向Intel/AMD的某个人询问这个问题。 - Aryabhatta
18个回答

10

回到1997年的时候,当我在学校没有连接电缆时,我曾经在TI-83计算器上做过这个。

通常情况下,你只需要编写一个汇编程序,使用TASM进行构建,然后通过连接电缆将其传输到计算器中。但是如果我感到无聊并想组合一些小东西,我已经记住了足够的字节指令来输入某些操作。

顺带一提 如果程序有漏洞,这当然是很有趣的,因为它可以轻松地破坏整个计算器的RAM。那么你就得按住ON按钮和/或拿掉AAA电池,希望这足以恢复计算器(除了存储在内存中的任何程序)。否则要进行硬重置,就必须使用螺丝刀解开一个特殊的备用电池。好时光......


3
这个问题的简短答案(实际上所有答案都是如此):当没有工具可用来为您完成它时。 - dmckee --- ex-moderator kitten

8

历史原因: 您正在运行需要在前面板上切换其引导代码的机器。(是的,这是在前几代机器中经常做的。)

与您想要的现代原因不同: 当您编写汇编程序时,必须弄清该过程。


还有许多其他情况,编写汇编程序实际上并不涉及以二进制编写任何函数/程序。 - Potatoswatter
4
除非你要编写第一个汇编程序,否则不需要用机器码来编写汇编语言程序。但是,你必须手动(或心算)翻译足够的代码,以了解汇编程序的作用。我坚持我的答案。 - dmckee --- ex-moderator kitten
1
这是在个人电脑的早期完成的。我看到了一篇关于 IMSAI 计算机的评论,称赞它在前面板上拥有桨式开关,比 Altair 8800 的开关要好得多。(如果我没记错的话,这也是一篇赞扬它易于组装的评论,因为评论者只需要拿出他的示波器一次即可。) 不过那是很久以前的事了。 - David Thornley
@David:即使是套件式电脑也比我早几年,我从未真正做过这个。不过我一直在琢磨着建立一个微控制器板来支持这种操作。 - dmckee --- ex-moderator kitten

4
如果没有[反]汇编器可用,您就需要手动翻译原始的PowerPC指令流。在固件黑客攻击中,我曾花费大量时间查看原始的PowerPC指令流以便能够识别和手动组装一些种类的指令。某些ISA比其他ISA简单得多。RISC遵循简单的格式,很容易定位自己,因为指令通常具有相同的长度并对齐到字边界。另一方面,x86-64充满了可变长度的编码和前缀代码。在FPGA项目或涉及定制电路时,非常常见的是设计某种指令流并以二进制手动编码。请尝试安装http://homepage.mac.com/potswa/source/DisDave.sit来移植一个反汇编器。

3

3
动态代码生成:
如果您需要解决一个非常简单的问题,并且性能很重要,通常最好分析问题空间并动态生成专门的函数来解决问题。
一个实际的例子是高性能数学计算与稀疏矩阵。这通常涉及到数千至数百万次数字数组的乘法。由于许多矩阵元素可能为零或一,因此如果删除所有琐碎的乘法,可以节省大量时间。
为了做到这一点,一个小的代码生成器可以分析矩阵并动态生成矩阵算术的机器码。如何实现这一点可以使用JIT库(或内置语言功能)或非常简单的方案。
对于稀疏矩阵乘法的情况,您可以通过将不同情况的预构建代码片段粘合在一起来获得良好的性能。这可以用50行C代码完成。

3
当我在海军服役时进行培训(大约在1986年左右),我们有一台电脑,我们被赋予学习电子故障排除,而不是编程故障排除,该电脑是通过将二进制信息输入到计算机前面进行编程的,我们必须告诉教练他们在机器中破坏了什么,基于结果以及对硬件的故障排除。据我所知,可能仍然有这些机器之一。
我希望我能找到它的源代码,我实际上写了一个模拟器和一种语言的编译器。令人惊讶的是,你可以用1024字节的内存完成多少工作! :)

2
  1. 利用未记录的操作码(现代几种处理器上仍然存在!)不久前必须在基于6502的处理器上进行此操作。
  2. 当将程序烧录到使用微控制器的自制电路中时。微控制器现在可用于各种事情。

2

我记得曾经看到Woz在机器语言中编写了第一版Apple BASIC(是针对Apple I还是Apple II我不确定)。在他们拥有存储设备之前,你需要在监视器中输入十六进制代码。


2
即使你跳过汇编语言直接使用机器码,你也不会使用二进制,而是使用十六进制。
在学校里,我曾经不得不使用调试器在内存中修补代码,没有汇编器的帮助。虽然有趣,但这是一项几乎在嵌入式系统调试之外毫无价值的技能。
此外,需要注意的是汇编中使用的操作码助记符应该与实际操作码具有一对一的对应关系(因此称为“助记符”),因此您不能通过手动打出机器码来做任何汇编无法完成的事情。汇编器的作用是将助记符转换为操作码(还确定应使用特定指令的哪个版本-立即 vs 间接MOV等),标签转换为地址以及类似的任务。
了解汇编器内部发生的事情很好,但除非你在寻找汇编器中的错误,黑客入侵嵌入式装置或在一个非常奇怪的情况下进行MacGyver操作,否则这几乎永远不会发生。

1
没有区别。十六进制(或八进制,我听说很多老手更喜欢这个(不同的字长,你知道吗?))只是二进制的简写形式。 - dmckee --- ex-moderator kitten
1
太阳很热,水是湿的。但是,你更愿意输入“01011010”还是“5A”?此外,我还没有见过可以让你输入二进制的调试器;我见过的所有调试器都需要十六进制或(呕)八进制输入。 - 3Dave

1

我没有汇编器来编写我的八位Atari,所以我直接编写了机器码。要从BASIC启动代码,您可以将代码编写为十进制数据字节或字符串形式。(是的,您实际上可以在字符串中编写代码,您无法键入的256个字符代码中唯一的字符代码是155-返回的代码。幸运的是,没有6502机器码指令具有该值,因此只有当分支恰好向后101个字节(-101 = 155)时才会出现问题。)

我仍然记得一个常见的启动计时器的代码片段:

104 (pla)
169, 7 (lda #7)
162, 6 (ldx #6)
160, 10 (ldy #10)
76, 92, 228 (jmp 0xE45C)

近年来,我参加了一些大小优化汇编比赛。尽管大部分代码都是汇编,但你仍然需要确切地知道汇编器生成哪些指令,以便知道它们占用多少字节。此外,有时你会使用一些技巧,比如让一些字节既作为数据又作为代码,或者让一些字节根据你输入的是第一个字节还是在指令中间输入而成为不同的指令。然后你会在汇编代码的中间将指令编写为数据字节。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接