我当时在看欧拉计划问题48:
系列1 1 + 2 2 + 3 3 + ... + 10 10 = 10405071317。
找到该系列的最后十位数字,1 1 + 2 2 + 3 3 + ... + 1000 1000。
在Python中,我可以单行执行此操作:
sum((x**x for x in xrange(1,1001))
但是,这相当于100条装配线,这确实是一个挑战。
我是否应该在组装中解决这些难题,以便对底层编程有所了解并了解计算机的实际工作原理?
我当时在看欧拉计划问题48:
系列1 1 + 2 2 + 3 3 + ... + 10 10 = 10405071317。
找到该系列的最后十位数字,1 1 + 2 2 + 3 3 + ... + 1000 1000。
在Python中,我可以单行执行此操作:
sum((x**x for x in xrange(1,1001))
但是,这相当于100条装配线,这确实是一个挑战。
我是否应该在组装中解决这些难题,以便对底层编程有所了解并了解计算机的实际工作原理?
Answers:
除了学习汇编,我相信学习如何编译像C这样的低级语言非常有价值。所以我的答案是肯定的,但是由于我喜欢低级编程,所以我又可能有偏见。
例如,仅了解如何编译简单的语句。以下功能,
int func(int val)
{
int num = val * 5;
return num;
}
...成为(至少有趣的一点):
movl %edi, -20(%rbp)
movl -20(%rbp), %edx
movl %edx, %eax
sall $2, %eax
addl %edx, %eax
此代码从堆栈中获取参数(val,参数为func),将其左移2位(乘以2 ^ 2或4),然后将原始值添加到结果中。最终结果是乘以5。像这样的示例说明了许多要注意的事情,例如编译器优化。与其调用直接乘以5的指令,不如将两个位置乘以4并将其原始值相加。我发现这样的例子可以极大地提高我对底层事物的理解。
使用-S
选项从gcc生成汇编程序输出。但是,请注意结果会随编译器和优化级别的不同而不同。
无论如何,我认为成为一名汇编语言程序员与理解Assembly并不相同。同样,我觉得用C之类的语言编程并了解如何将其放入机器代码中是一种宝贵的实践。
实际上可能不需要编写汇编程序(其中大多数是有关系统初始化和调用约定的详细信息)。
如果您尝试在没有源代码的情况下调试某些内容,则值得了解一些内容。
但是绝对值得至少在“ C”和指针(本质上是高级汇编程序)级别理解机器,以便您知道为什么在循环中将字符串压缩一百万次是不好的。
for i in range(1000000): s = s + '.'
不会使我重用的“优化”版本更糟s
。类似地,其他一些开发使具有C知识的合理假设和朴素的实现无效。但总的来说,它比有害更有用。请记住,语言实现有时比您更聪明;)
我小时候做过很多汇编程序,但我认为这对理解汇编程序之外的任何内容都没有帮助。如果您看一下现代汇编程序,无论如何,它们都是宏语言。我通常讨厌类比,但是不管怎么说,这会不会:了解汽车引擎的工作原理是否会使您成为更好的驾驶员?
我一直在理解汇编程序的方式是通过用高级语言编写程序,然后(至少希望)用功能上等效的汇编代码段替换部件。这意味着我要使用HLL来解决它们对组织和解决高级问题的好处,并且我要使用asm来打击金属。
(当我谈论用HLL编写的主机程序时,我指的是在尝试学习x86_64 asm时使用C或ObjC,而在Z80、6502和6809 asm上进行操作时则指的是BASIC)。