printf 几乎是你想用来学习汇编的最后一个函数,库调用会稍后出现,但你不需要使用库/系统调用。使用调试器也会使用系统调用将您带入老鼠巢。试试这样的方法,特别是如果你想从这个练习中学习汇编语言。
unsigned int fun ( unsigned int a, unsigned int b )
{
return(a^b^3);
}
gcc -O2 -c so.c -o so.o
objdump -D so.o
Disassembly of section .text:
0000000000000000 <fun>:
0: 89 f0 mov %esi,%eax
2: 83 f0 03 xor $0x3,%eax
5: 31 f8 xor %edi,%eax
7: c3 retq
我强烈建议您避免将 x86 作为您的第一个指令集。尝试更清洁的东西...
arm-none-eabi-gcc -O2 -c so.c -o so.o
arm-none-eabi-gcc -O2 -c -mthumb so.c -o so.o
arm-none-eabi-objdump -D so.o
00000000 <fun>:
0: 2303 movs r3, #3
2: 4059 eors r1, r3
4: 4048 eors r0, r1
6: 4770 bx lr
msp430-gcc -O2 -c so.c -o so.o
msp430-objdump -D so.o
00000000 <fun>:
0: 3f e0 03 00 xor #3, r15 ;#0x0003
4: 0f ee xor r14, r15
6: 30 41 ret
非常认真地认为这是第一个指令集,msp430 接近它,但这个最有意义,不幸的是 gnu 汇编器语法与书籍不匹配,而且不幸的是当时用八进制思考的世界,我们认为是十六进制现在...
pdp11-aout-gcc -O2 -c so.c -o so.o
pdp11-aout-objdump -D so.o
00000000 <_fun>:
0: 1166 mov r5, -(sp)
2: 1185 mov sp, r5
4: 15c0 0003 mov $3, r0
8: 1d41 0006 mov 6(r5), r1
c: 7840 xor r1, r0
e: 1d41 0004 mov 4(r5), r1
12: 7840 xor r1, r0
14: 1585 mov (sp)+, r5
16: 0087 rts pc
适合所有人的模拟器或硬件,最好在模拟器中学习而不是在真实硬件上学习...
我通过编写反汇编程序学到的大多数指令集,arm 和 thumb 都属于这一类,因为它们的指令长度是固定的(如果你避免使用 thumb2 扩展)。或者只是写一个模拟器,msp430和pdp11就属于这一类。后者要么是一个下午的项目,要么是一个长周末的项目。你会比一般人更了解每个指令集,甚至有些人已经使用它编程了一段时间。
如果您坚持使用 x86(我强烈建议您不要这样做),请使用 8086/8088 模拟器(如 pcemu)并坚持使用原始指令集,使用 nasm 或 a86 或任何需要的东西来执行此操作。即使在当时,它也不是很好的指令集,但当时比现在更有意义。 bitsavers 很好地扫描了原始英特尔文档的搜索功能版本,是最好的起点。
arm 文档在 arm(正在寻找 armv5 的架构参考手册,我想他们现在称之为)。 msp430 看看wikipedia 指令集有没有pdp11 google 一下,用C 机器码反汇编找出语法。
如果你真的想玩得开心,从 opencores 获取 amber core 是 arm2/3,几乎所有指令都与 armv4 及更高版本相同,可以使用 gnu 工具。使用 verilator 构建和模拟并从内部查看正在工作的处理器。理解就像让 100 名程序员给他们一个编程任务并获得 1 到 100 种不同的解决方案一样,拿一个指令集并给 100 名工程师执行它的任务,你会得到 1 到 100 种不同的解决方案。 Arm 本身已经为相同的指令集重新设计了他们的内核数次,更不用说为数不多的合法克隆了。
推荐顺序 pdp11、msp430、thumb、arm,然后是 mips,如果您仍然觉得需要拆卸一些 x86。 PIC12/14 简单且具有教育意义(你应该花半小时到一个小时来制作一个模拟器),6502、z80、8051、6800 和其他一些在历史上也像 x86 一样具有教育意义,可以查看文档,但是不需要编写程序。如果您从一个好的开始,那么从第二个指令集开始,每个第 N 个指令集都会容易得多。它们的相似之处多于不同之处,但是您确实可以看到不同的东西,例如如何在 mips 中没有标志的情况下做事等……我遗漏了其他几个仍然在硅片中可用或由于各种原因而有趣的指令集。
另一种方法是安装 clang/llvm 并快速或更长时间地查看 llc 可以生成的每个指令集(编译为位码/字节码,然后使用 llc 对任何指令集进行后端处理)。就像上面一样,使用相同的代码并至少使用该编译器查看不同的指令集是什么样的,它的设置非常有教育意义,有助于从心理上了解如何将编程任务分解为这些原子步骤。