[汇编]小议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]