阿男bluedash 发表于 2013-1-15 23:42:32

[汇编]小议MacOS下的汇编环境

在读《Assembly Language Step by Step - Programming with Linux》这本书时,里面有这样一段代码:

;Executable name : EATSYSCALL;Version         : 1.0;Created date    : 1/7/2009;Last update   : 2/18/2009;Author          : Jeff Duntemann;Description   : A simple program in assembly for Linux, using NASM 2.05,;    demonstrating the use of Linux INT 80H syscalls to display text.;;Build using these commands:;    nasm -f elf -g -F stabs eatsyscall.asm;    ld -o eatsyscall eatsyscall.o;SECTION .data; Section containing initialised dataEatMsg: db "Eat at Joe's!",10EatLen: equ $-EatMsgSECTION .bss; Section containing uninitialized dataSECTION .text; Section containing codeglobal _start; Linker needs this to find the entry point!_start:nop; This no-op keeps gdb happy...mov eax,4; Specify mov ebx,1; Specify File Descriptor 1: Standard Outputmov ecx,EatMsg; Pass offset of the messagemov edx,EatLen; Pass the length of the messageint 80H; Make kernel callMOV eax,1; Code for Exit Syscallmov ebx,0; Return a code of zeroint 80H; Make kernel call

上面的代码通过80h中断来调用Linux的syscall,来向屏幕输出Eat at Joe's!这串字符。这个代码在MacOS下不能直接用的,因为MacOS的内核是FreeBSD的port,所以syscall的调用要遵从FreeBSD的习惯。

上面的例子中我们可以看到,在Linux中给syscall传参数主要靠寄存器(eax, ebx, ecx...),而在MacOS中调用则靠堆栈。这是由于Linux和FreeBSD在内核的实现上面有很大不同。因此,可以将上面的代码改写,使其可以在MacOS下面编译运行。

以下是改造后的代码:

SECTION .data; Section containing initialised dataEatMsg: db "Eat at Joe's!",10EatLen: equ $-EatMsgSECTION .bss; Section containing uninitialized dataSECTION .text; Section containing codeglobal _start; Linker needs this to find the entry point!_syscall:               int   0x80            ;system call    ret_start:nop; This no-op keeps gdb happy...push dword EatLen; Pass the length of the messagepush dword EatMsg; Pass offset of the messagepush dword 1; Specify File Descriptor 1: Standard Outputmoveax,0x4; System call number (sys_write)call _syscall; Make kernel calladd esp, 12   ; Clean stack (3 arguments * 4)push dword 0; Return a code of zeromoveax,0x1; Code for Exit Syscallcall _syscall       ; Make kernel call

注意到参数都改用push入栈了,这是FreeBSD的习惯。

其次,我们将80h调用封装进了_syscall函数,这是FreeBSD的习惯(如果不将_syscall封装进函数直接调用,则还需将eax入栈,详细说明请参考)。

最后,用来编译代码的命令也不同:

nasm -f macho -geatsyscall.asmld -e _start -o eatsyscall eatsyscall.o

MacOS使用macho格式来保存可执行文件,此外在使用ld连接时,需要指定入口地址为_start。

更多关于MacOS下汇编的知识可以参考和。

http://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025

http://www.duntemann.com/assembly.html

http://orangejuiceliberationfront.com/intel-assembler-on-mac-os-x/

http://salahuddin66.blogspot.com/2009/08/nasm-in-mac-os-x.html

http://www.freebsd.org/doc/en/books/developers-handbook/x86-system-calls.html
页: [1]
查看完整版本: [汇编]小议MacOS下的汇编环境