回答
诚然这是个人的偏见,你怎么喜欢学习编程。
但相对于在特定的汇编语言,我发现了一个办法这对我来说已经不是阅读汇编语言指令集参考手册和/或书籍(如有的话)更为有用。
我通常做找出如何组装一个新的CPU工作/一个CPU不知道的我一个操作系统平台,我不还制作是利用开发工具链。像这样:
为自己安装目标CPU的(交叉)编译器和反汇编程序。现在,GNU gcc的/ binutils无处不在通常意味着这是
gcc
和objdump -d
。创建一批的小程序/小片的源代码,如:
extern int funcA(int arg);
extern int funcB(int arg1, int arg2);
extern int funcC(int arg1, int arg2, int arg3);
extern int funcD(int arg1, int arg2, int arg3, int arg4);
extern int funcE(int arg1, int arg2, int arg3, int arg4);
extern int funcF(int arg1, int arg2, int arg3, int arg4, int arg5);
extern int funcG(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);
extern int funcH(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6,
int arg7);
int main(int argc, char **argv)
{
printf("sum of all funcs: %d\n",
funcA(1) + funcB(2, 3) + funcC(4, 5, 6) + funcD(7, 8, 9, 10) +
funcE(11, 12, 13, 14, 15) + funcF(16, 17, 18, 19, 20, 21) +
funcG(22, 23, 24, 25, 26, 27, 28) + funcH(29, 30, 31, 32, 33, 34, 35));
return 12345;
}
编译这些与编译器优化和拆卸生成目标代码。
代码的结构非常简单,足以说明如何运行。到函数调用,传递参数和返回值,管理寄存器空间 wrt。在进行函数调用时寄存器被保留/不稳定。它还会显示一些用于初始化常量数据的基本汇编代码,以及像堆栈访问和管理那样的“粘合”。将此扩展为简单的C语言结构,如循环和
if
/else
或switch
语句。始终保持对外部未定义功能几个电话,因为这样做会防止编译器优化,从扔你所有的“测试代码”出来的,而当你使用if()
测试switch()
,对argc
(或其他功能参数)谓词,因为编译器无法预测即(并且因此优化代码的“构建块”)。延伸此使用含有不同的基本数据类型的序列
struct {}
和class {}
定义,以便找出编译器在存储器中,其中汇编指令用于访问字节/字/整型/多头/浮标如何安排这些等
所有这些作品的测试代码,你可以故意改变(例如,使用不同的操作比+
),和/或进行更复杂,以了解更多有关指令集和ABI的某些片段。
你做了之后,看着在输出中,找到平台ABI的副本(电子或没有)。其中包含规则手册,说明如何完成上述工作/为什么完成上述工作,它将帮助您了解这些规则适用于特定平台的原因。了解上述内容非常重要,因为在编写自己的汇编代码时,必须将其与其他非汇编代码(除非用于纯演示)进行交互。这就是你需要遵守规则的地方,所以即使你不了解他们,至少知道规则手册在哪里。
只有在那之后,我才建议你实际追踪特定平台的指令集参考。
这是因为,当你通过上述第一消失了,那么你已经有足够的经验/你已经看到已经足以启动一个小的C程序,编译它到汇编源,修改了一下,组装并链接它,看看你的修改是否做它应该做的。
试图在这个阶段使用一些更少见的/专门的指令会容易得多,因为你已经看到了函数调用是如何工作的,需要什么样的粘合代码来将你的程序集与界面的其他部分程序,你已经使用了工具链,所以你不需要从头开始完全。
即,要总结这一切,我的建议是从学习汇编自上而下,而不是从下往上。
旁注:
为什么我建议使用编译器优化这种简单的例子分析编译器生成的汇编代码是什么时候?
那么,答案是因为,违反直觉的一些,生成的汇编代码是简单得多如果你让编译器优化地狱的东西。没有优化,编译器通常会创建“愚蠢的”代码,例如将所有变量放入堆栈,从那里保存并恢复它们,无论您看到什么原因,注册保存/恢复/初始化只是为了覆盖下一条指令以及更多这样的内容。因此,发射的代码量要大得多。它夹杂着粗糙,而且很难理解。编译器优化可以将这个问题修剪到最基本的部分,这就是你想要了解平台ABI以及可以理解的东西。因此,使用编译器优化。
这是一个非常好的idead/answer。非常感谢。 – gideon 2014-02-18 07:03:44
这是我见过的最好的答案之一。 – 2016-05-07 07:55:13
- 1. 芯片组信息 - AMD或英特尔
- 2. 英特尔TBB和Cilk Plus线程亲和力英特尔MIC
- 3. 英特尔ESG教程和示例需要
- 4. 英特尔SSE和AVX示例和教程
- 5. 什么是英特尔®安装和配置软件(英特尔®SCS)
- 6. 我如何安装英特尔编译器和英特尔mpi的提升?
- 7. 英特尔HAXM安装失败
- 8. 我不能安装英特尔haxm
- 9. 在组装中设置文本和背景英特尔
- 10. 英特尔AVX2组件开发
- 11. 创建使用英特尔组件
- 12. 与英特尔伽利略gen2的英特尔xdk守护进程
- 13. 英特尔xdk应用程序安装替换以前的apk
- 14. 分割的64位英特尔(和非英特尔)处理器
- 15. FFT使用英特尔MKL和英特尔IPP
- 16. 英特尔TBB使用的线程数
- 17. 英特尔XDK(在HTML5应用程序)
- 18. 弃用警告(哈特尔教程)
- 19. 正则表达式教程或书
- 20. Webots的资源(教程或书籍)
- 21. jQuery与Rails 3.1.3电子书或教程?
- 22. 学说2教程或书籍?
- 23. 我使用英特尔Cilk的加数组符号英特尔Cilk的加数组符号
- 24. 如何开始使用图书馆英特尔ipp?
- 25. Angular2英雄教程 - 英雄课
- 26. 针对OpenCL应用程序安装安装英特尔SDK,并获得以下
- 27. 英特尔8086处理器
- 28. 英特尔XDK分层表
- 29. 英特尔Fortran损坏DLL
- 30. 英特尔XDK - 通过pushMobi
我不了解有关nasm教程,但可以获取[Intel Software Developer Manuals](http://www.intel.com/content/www/us/en/processors/architectures-software-developer- manuals.html),你应该发现很有帮助。 – 2013-03-08 15:48:14
intel.com上的教程?这听起来像个可笑的玩笑。从[Paul Carter的教程](http://www.drpaulcarter.com/pcasm/)开始。令人惊讶的是,它基于NASM。当您掌握32位程序集时,请切换到64. – 2013-03-08 16:27:52
我推荐Ray Seyfarth介绍适用于Linux的64位英特尔汇编语言编程。本书使用YASM而不是NASM,但YASM接受AFAIK几乎所有的NASM代码,并且还支持DWARF2调试数据格式等。本书也有一些SSE和AVX代码,并且它只假定一些编程背景并解释二进制和十六进制数字等。我已经在DOS时间学习了x86程序集,但是本书可以作为Linux x86-64程序集中有用的参考。 – nrz 2013-03-08 21:39:05