是否有理由用纯二进制编写代码?

时间:2010-02-19 21:55:10

标签: language-agnostic binary computer-science

当ASM不够低时,是否存在某种情况?毕竟,汇编程序仍然必须汇编。有没有人用二进制编写程序?我只是想知道为什么这样做可能是实用的,或者即使它可以在现代计算机上存在的理论上的原因。

18 个答案:

答案 0 :(得分:9)

早在1997年,当我在学校并且无法使用链接电缆时,我曾经在TI-83计算器上执行此操作。

通常在那个时候,您只需编写汇编程序,使用TASM构建它,然后通过链接电缆将其传输到计算器。但是如果我感到无聊并想把一些小东西放在一起,我就已经记住了足够的字节指令,以便能够为某些事情输入它们。

旁注当然,如果程序中存在错误,这很有趣,因为它很容易破坏整个计算器的RAM。那么你必须按住ON按钮和/或移除AAA电池,并希望这足以恢复计算(没有内存中的任何程序)。否则要进行硬重置,您必须使用螺丝刀拧下特殊备用电池。好时光......

答案 1 :(得分:8)

历史原因:您正在运行一台需要在前面板上切换启动代码的计算机。 (是的,这已经完成了。通常在前几代机器中。)

不是你正在寻找的现代理由:当你编写汇编程序时,你必须弄清楚这个过程。

答案 2 :(得分:4)

你知道了 - 如果没有[dis]汇编程序可用。我一直在固件黑客的情况下,我花了足够的时间查看原始PowerPC指令流,以便能够识别和手工组装几种指令。 (我最终移植了一个反汇编程序:http://homepage.mac.com/potswa/source/DisDave.sit,如果你能设法安装它。)

有些ISA比其他ISA简单得多。 RISC遵循简单的格式,并且很容易定位自己,因为指令通常具有相同的长度并与字边界对齐。另一方面,x86-64充满了可变长度编码和前缀码。

FPGA项目中或涉及自定义电路时,设计某种指令流并以二进制形式手动编码是很常见的。

答案 3 :(得分:3)

当我在海军时期(1986年左右)进行训练时,我们有一台计算机,我们学习电子故障排除,而非编程故障排除,通过在计算机前面输入二进制信息进行编程,我们必须根据结果以及硬件故障排除告诉讲师他们在机器中发生了什么。据我所知,可能还有其中一台机器。

我希望我能找到它的源代码,我实际上写了机器的模拟器和机器语言的编译。用1024字节的内存完成多少工作真是令人惊讶! :)

答案 4 :(得分:3)

当您手动黑客二进制格式时,A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux会这样做。

答案 5 :(得分:3)

动态代码生成:

如果您有一个非常简单的问题需要解决,并且性能很重要,通常最好分析问题空间并动态生成专门的函数来解决问题。

一个实际例子:使用稀疏矩阵的高性能数学。

这通常涉及数字数组的增加,数千至数百万次。由于许多矩阵元素可能为0或1,因此如果删除所有简单的乘法,则可以节省大量时间。

为此,一个小代码生成器可以分析矩阵并生成矩阵运算的机器代码。如何使用JIT库(或内置语言功能)到非常简单的方案。

对于稀疏矩阵乘法的情况,只需将不同情况的预构建代码片段粘合在一起就可以获得很好的性能。这可以用50行C代码完成。

答案 6 :(得分:2)

我记得读过Woz用机器语言编写了第一个Apple BASIC(Apple I?Apple II?)。在他们有存储设备之前,您需要在显示器中输入十六进制代码。

答案 7 :(得分:2)

即使您发现自己正在跳过汇编程序并直接进入机器代码,您也不会使用二进制文件,而是使用十六进制代码。

在学校里,我不得不使用调试器在内存中修补代码而不需要汇编程序。虽然很有趣,但这是一项在嵌入式系统调试之外几乎没有任何价值的技能。

另外,考虑到汇编中使用的操作码助记符应与实际操作码(因此称为“助记符”)具有1:1的对应关系,因此您无法通过手动敲击机器代码来执行任何操作在集会中无法做到。汇编程序的作用是将助记符转换为操作码(还要确定应使用哪个版本的特定指令 - 例如,直接与间接MOV),地址标签和类似任务。

很高兴知道汇编程序内部会发生什么,但是除非你在汇编程序中查找错误,黑客攻击嵌入式小工具或MacGyvering出于真正非常奇怪的情况,否则几乎不会出现这种情况。

答案 8 :(得分:2)

  1. 利用无证件操作码(仍有几个现代处理器!)必须这样做 不久前,基于6502的处理器。
  2. 使用微控制器将程序闪存到家用电路时。如今,微控制器可用于各种各样的事情。

答案 9 :(得分: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)

近年来,我参加了一些尺寸优化组装比赛。尽管大多数代码都是汇编代码,但您仍然必须确切知道汇编程序生成哪些指令,以便了解它们的字节数。此外,有时您会使用一些技巧,例如将某些字节用作数据和代码,或者根据您是输入第一个字节还是输入指令的中间,使某些字节为不同的指令。然后在汇编代码中间将指令写为数据字节。

答案 10 :(得分:1)

在一个后世界末日的世界里,所有的键盘和显示器都被摧毁了,将俄罗斯方块编入计算机的唯一方法是通过前面板上的切换,是的。

但严重的是,为什么有人想做这样的事情?

编辑:显然有人在那里设计必须以二进制编程的处理器,直到他们可以在他们的处理器上运行汇编程序,但他们只是一小群人。

答案 11 :(得分:1)

您可以通过使用原始机器代码而不仅仅是汇编语言来获益。例如,考虑通过电子邮件发送二进制文件,但使用不知道如何解码附件的电子邮件程序。有一段时间,有几个人编写了可以解码附件其余部分的小程序,但程序中的所有内容都是可打印的字符。因此,您解码附件,将电子邮件的正文保存为whatever.com,然后执行它。它会解码附件并编写一个你可以执行的二进制文件。

另一个例子,多年前在Fidonet上有一个相当简单的挑战:编写一个程序,只打印出一个在每次运行时递增的数字 - 但是(使它变得棘手的部分)它不允许使用任何外部文件或其他存储来完成这项工作。为了防止这种情况变得太无聊,它也是代码高尔夫类的东西,尽管测量的大小是可执行字节,而不是源代码。这次挑战的相当一部分内容使用了自我修改代码,这些代码严重依赖于指令的编码方式等。

寻找一秒钟,我看到我的其中一个尝试仍然有源代码:

.model tiny,c
.286
.code
.startup
main proc
    mov     si,offset count
    inc     byte ptr [si]
    mov     al, [si]
    mov     bx,4090h
    shr     al, 4
    call    convert
    lodsb
    and     al,0fh
    mov     byte ptr end_convert, 08bh
convert:
    add     al,bl
    daa
    adc     al,bh
    daa
    int     29h
end_convert:
    ret
    db      0d6h
;    mov     dx, si
    mov     ah,3ch
    xor     cx, cx
    int     21h
    xchg    bx, ax
    mov     dx,offset main
    mov     cx,offset the_end - offset main
    int     21h
    ret
main endp

count:
        db 0
name:
        db 'c.com', 0
the_end:
    end

我现在最好退出,在我负责任何人中风之前(希望我不会太迟......)

答案 12 :(得分:0)

从二进制到汇编程序来理解转储过去并不常见。

但不使用汇编程序?我想不出任何理由。汇编程序已经在编写裸机。唯一的好处是可以为实际(二进制)指令使用诸如“添加”之类的标签。等

答案 13 :(得分:0)

好吧,如果您是芯片开发人员,可以使用hex在RAM或ROM中编写一些基本的引导加载指令,而不是使用汇编程序。我已经为我写的一个色情内容这样做了。

实际上,在你完成之后,下一步就是在Perl中编写一个基本的汇编程序。

答案 14 :(得分:0)

如果您正在创建翻译。也许您已完成解释器,但不是解析器。您可以通过用纯二进制编写待解释程序来测试解释器。

答案 15 :(得分:0)

为新团队成员的hazing仪式。

答案 16 :(得分:0)

一个非常酷的例子是这个着名的多语言,这是一个有效的DOS .COM文件,因为其源代码中的ASCII兼作二进制x86指令! http://ideology.com.au/polyglot/polyglot.txt

更无聊的例子......

许多处理器将ISA指令实现为更原始的微指令序列(基本上是数据路径控制信号的集合),这些指令在微代码ROM中被“微编码”。

对于一个足够简单的处理器,你可以直接用二进制编写微代码而不是用助记符语言编写它。或者,如果您正在对一个处理器进行逆向工程,您可能不知道它的微指令集,只需要猜测微指令的格式......在这种情况下,您可能也在使用二进制文件。无论哪种方式,这都比汇编语言更低。

有时像6502这样的旧处理器的代码使用了没有官方助记符的无证指令,因此你必须编写二进制值而不是汇编指令。

答案 17 :(得分:0)

对于大学项目,我必须用VHDL(硬件描述语言)设计一个简化的微控制器。为了测试它,我用二进制编写了一个非常简单的程序,因为它是将程序输入模拟微控制器的最方便的方法。