我希望去学习x86汇编语言。我在Mac上,和我假设大多数x86教程/书籍使用的意思的Windows代码。

那如何代码上运行OS影响的代码做什么,或者确定是否代码甚至工作?我可以遵循一个基于Windows的教程,并修改了一些命令,使之适用于Mac的工作相对容易?更一般地,是有什么棘手的是一台Mac汇编编程,具体而言,应该知道吗?谢谢!

有帮助吗?

解决方案

(当然,以下所有适用的以86和x86-64汇编语言,对IA-32和AMD64处理器和操作系统。)

其他答案目前可见的是正确的,但是,在我看来,错过了这一点。 AT&T与英特尔的语法是一个完整的非问题;任何像样的工具将有两种语法工作,或者有,做了对口或更换。他们聚集在同一反正。 (普罗蒂普:你真的想使用Intel语法所有正式处理器文档中则AT&T语法仅仅是一个巨大的头痛。)是的,寻找合适的标志传递给汇编器和链接可能会非常棘手,但你会知道什么时候你得到它,你只需要每OS做一次(如果你还记得它的地方写下来!)。

组装说明自己,当然是完全操作系统无关。该CPU的不关心的它运行的是什么操作系统。除非你正在做的非常低的水平两轮牛车(也就是操作系统的开发),螺母和的操作系统和CPU的交互方式几乎完全不相干的螺栓。

外界

汇编语言的麻烦来,当你与外部世界的互动:操作系统内核,以及其他用户空间代码。用户空间是最棘手的:你必须得到ABI权利或你的汇编程序几乎是没用的。此部分通常不是操作系统之间移植,除非使用的蹦床/的thunk(抽象基本上另一层必须被重写为每次打算支持OS)。

的ABI的最重要的部分是任何调用约定为C样式的功能。他们在做什么是最常用的支持,你很可能会与你正在编写组件中的接口。昂纳雾保持在他的网站几个很好的资源;的调用约定是特别有用的详细描述。在他的回答,诺曼·拉姆齐提到PIC和动态库;在我的经验,你通常没有与那些打扰,如果你不想。静态链接为汇编语言的典型用途(如改写内环或其他热点的核心功能)工作正常。

在调用约定工作在两个方向:您可以从组装或装配从C调用C后者往往更容易一点,但有没有很大的区别。从组件调用C让你使用之类的东西C标准库输出功能,而从C调用组件通常是如何访问单个性能关键功能的组件实现。

系统调用

其他的事情,你的程序将做的是使系统调用。你可以写一个完整的和有用的汇编程序从未调用外部C函数,但是如果你想写一个纯汇编语言程序,不外包有趣的东西给别人的代码,你要的需要系统调用。而且,不幸的是,系统调用是完全和每个操作系统上完全不同。 Unix风格的系统调用,你需要包括(但最稳妥不限于!)opencreatreadwrite,和所有重要的exit,与mmap沿,如果你喜欢动态分配内存。

虽然每个OS是不同的,最现代的操作系统遵循一般模式:加载呼叫要到一个寄存器中的系统的数量,典型地EAX在32位代码,然后加载参数(你如何做到这一点而变化似地),最后发出中断请求:它是Windows NT的内核或INT 2E为Linux 2.x和FreeBSD的(而且,我相信,OSX)INT 80h。然后内核接管,执行系统调用,并返回EXECUT离子程序。根据不同的操作系统上,它可能垃圾寄存器或堆栈系统调用的一部分;你必须确保你阅读系统调用文档平台是肯定的。

SYSENTER

的Linux 2.6内核(而且,我相信,Windows XP和更新的,虽然我从来没有真正尝试过在Windows上)还支持一个更新,更快的方法来进行系统调用:由Intel在新的Pentium处理器推出了SYSENTER指令。 AMD的芯片有SYSCALL,但很少有32位操作系统使用它(尽管它是64位的标准,我想,我还没有做出直接的系统从64位程序调用,所以我不知道在这)。 SYSENTER是显著更复杂的设置和使用(参见,例如, Linus Torvalds的关于实施SYSENTER对Linux 2.6 支持:“我是一个恶心的猪,并以此为荣启动。”)我个人可以证明它的特殊性;我曾经写道,直接下达SYSENTER到Linux 2.6内核的汇编函数,和我的还是的不明白的各种堆栈和寄存器,得到它的工作技巧......但工作不是没有!

SYSENTER稍微快于发放INT 80h,因此它的用途是期望的时可用。为了更容易编写既快速又移植的代码,Linux的映射一个名为linux-gate到每一个程序的地址空间VDSO;调用这个VDSO特殊功能将发布最快的机制系统调用。不幸的是,使用它通常是更多的麻烦比它的价值:INT 80h是如此简单得多的小汇编程序,这是值得的小速度损失的事情。除非你需要极致性能......,如果你需要,你可能不希望反正叫成VDSO,你知道你的硬件,那么你可以做的可怕的不安全的事情和问题SYSENTER自己。

所有其它

除了通过与内核和其他程序交互提出的要求,有操作系统之间极少,极少的差异。大会暴露了机器的灵魂:你可以工作,只要你喜欢,和你自己的代码中你没有被任何特定调用约定的约束。你必须在FPU和SSE单元的自由;您可以直接PREFETCH从内存中的数据流进入L1高速缓存,并确保它是热的,因为当你需要它;你可以Munge时间随意堆;如果你想用一个接口可以发出INT 3(正确配置;!祝你好运)外部调试器。这一切都不取决于您的操作系统。你唯一真正的限制是,你在环3上运行,而不是0环,等等一些处理器控制寄存器将无法给你。 (但是,如果你需要的,你写的操作系统代码,而不是应用程序代码。)除此之外,该机戳穿你!出去和计算

其他提示

一般来说,只要使用相同的汇编器和相同的体系结构(例如,NASM,和x86-64),则应该能够组装在Windows和Mac组件。

然而,要记住的是,可执行文件格式和执行环境可以不同是很重要的。作为一个例子,Windows可能会模拟/不同的方式处理某些特权指令到Mac,从而导致不同的行为。

另外的差的很大一部分是在程序如何与外界连通。

例如,如果你想显示一条消息给用户或读取的文件或分配更多的内存,你要问的OS通过使某种系统调用来做到这一点。那会 是OS的之间有很大不同。

在语言的语法本身作为你使用相同的汇编应该是基本一致的长。不同的装配有时会对语法或不同的宏但没有什么太难了稍微不同的顺序来适应。

在英特尔汇编语言的大分水岭是AT&T的语法和Intel语法之间。你会想为你的Mac电脑上使用相同的语法,你使用任何教程汇编。因为我相信达尔文的MacOS,是BSD变种,使用AT&T的语法和Microsoft汇编程序使用Intel语法,你必须要小心。

另一个不同提防是系统的应用程序二进制接口(ABI),它覆盖调用约定,堆栈布局,系统调用,等等。它们可以OS的基本之间不同,特别是当它涉及到的位置无关的代码和<强>动态链接即可。我有模糊的不愉快的记忆,石化尤其是基于PowerPC MacOS的复杂,但也许这是英特尔简单。

海贼王提醒的:学习x86_64的(也称为AMD64) - 它是手工编写汇编代码更加有乐趣,你会更适应未来

当我在我的编程旅游的访问之一期间浸入大会,即召开了我在每一个教程中的疑难杂症不能够在正确的二进制格式进行编译。最教程给elf(对于Linux)和aoutb(对于BSD),但与后者OS X抱怨(合乎逻辑的选择):

ld: hello.o bad magic number (not a Mach-O file)

Mach-O失败的格式,如果你man nasm你只有binaoutelf文件格式 - man ld没有更多的帮助 - macho是要为OS X的Mach-O的格式选项:

nasm -f macho hello.asm

写了旅程这里(包括链接,为大会和其他信息一个不错的TextMate束),但 - 是短暂的 - 上面是你所需要的上手

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top