Mac OS X下64位汇编与Linux下64位汇编的一些不同
1 首先系統(tǒng)調(diào)用號大大的不同;mac64和linux32的系統(tǒng)調(diào)用號也不同(雖然局部可能有相同)
2 mac64的系統(tǒng)調(diào)用號在:
/usr/include/sys/syscall.h可以查到,但是調(diào)用的時候其值要加上0x2000000,可以寫一個宏處理:
%define mk64 0x2000000+使用方式如下:
mov rax,mk64 1 ;exit NO mov rdi,0 ;error_code syscall3 如果在mac64下匯編要與C庫相鏈接,所有extern符號名前要加下劃線,包括入口點main:
extern _strerror extern _printf global _main _main:而linux64下匯編和C庫鏈接的時候必須去掉符號前的下劃線。
4 mac里的PIE(參考:http://blog.csdn.net/mydo/article/details/44906109),在直接使用絕對地址時會發(fā)出警告,如想去除警告,必須使用相對地址:
;mov rbx,addr ;上一條指令要換成下一條 lea rbx,[rel addr] mov rsi,[rbx]5 mac64下不允許將值賦到32位的絕對地址里去,比如以下指令出錯:
mov [addr],rax需要強制聲明為64位地址或者改用相對地址:
mov [qword addr],rax ;ok mov [rel addr],rax ;ok too但linux64下無此限制。
6 mac64和linux64對系統(tǒng)調(diào)用的C庫包裝有所不同,尤其是處理系統(tǒng)調(diào)用返回值的時候;比如mmap調(diào)用,linux64 C庫貌似不檢查參數(shù),而是依據(jù)syscall自身檢查;而mac64在調(diào)用前會檢查參數(shù),如果參數(shù)有誤,根本不會進行系統(tǒng)調(diào)用,直接設(shè)置errno,然后返回。再拿mmap來說,如果在mmap C庫函數(shù)上設(shè)斷點,那么在經(jīng)過N次的fast_syscall_stub之后:
-> 0x7fff8c4fc3b5 <+277>: callq 0x7fff8c4fd9e0 ; _dyld_fast_stub_entry(void*, long)才會進入斷點,所以要在fast_syscall_stub上設(shè)置條件斷點,忽略前面N次的捕獲(我測試的程序時或略前面28次),然后會進入kernel動態(tài)庫中的mmap函數(shù):
libsystem_kernel.dylib`mmap: -> 0x7fff8ad05a96 <+0>: pushq %rbp0x7fff8ad05a97 <+1>: movq %rsp, %rbp0x7fff8ad05a9a <+4>: pushq %r150x7fff8ad05a9c <+6>: pushq %r140x7fff8ad05a9e <+8>: pushq %r120x7fff8ad05aa0 <+10>: pushq %rbx0x7fff8ad05aa1 <+11>: movl %r8d, %r15d0x7fff8ad05aa4 <+14>: movq %rsi, %r14其對傳入mmap的參數(shù)進行了檢查,如果發(fā)現(xiàn)參數(shù)錯誤,不會調(diào)用真正的__mmap函數(shù),而是設(shè)置錯誤碼,然后根據(jù)不同的錯誤類型跳至對應的C庫錯誤處理函數(shù):
0x7fff8ad05b11 <+123>: movl $0x16, %edi0x7fff8ad05b16 <+128>: callq 0x7fff8ad03c53 ; cerror_nocancel下面是cerror_nocancel函數(shù)的反匯編:
libsystem_kernel.dylib`cerror_nocancel: -> 0x7fff8ad03c53 <+0>: movl %edi, -0x14a629d9(%rip) ; errno0x7fff8ad03c59 <+6>: movq %gs:0x8, %rax0x7fff8ad03c62 <+15>: testq %rax, %rax0x7fff8ad03c65 <+18>: je 0x7fff8ad03c69 ; <+22>0x7fff8ad03c67 <+20>: movl %edi, (%rax)0x7fff8ad03c69 <+22>: movq $-0x1, %rax0x7fff8ad03c70 <+29>: movq $-0x1, %rdx0x7fff8ad03c77 <+36>: retq而且最為關(guān)鍵的一點是,貌似mac64直接將系統(tǒng)調(diào)用錯誤碼通過rax返回,而不像linux64那樣返回的是錯誤碼的補碼。所以博文linux64匯編調(diào)用mmap的例子(博文鏈接:http://blog.csdn.net/mydo/article/details/45007989)里,syscall返回后的代碼必須改寫為如下代碼:
;syscall for mmapsyscallcmp rax,0xfffja nextpush raxmov [rel errno],raxpop raxor rax,-17 暫時想到這么多不同點,未完待續(xù)
總結(jié)
以上是生活随笔為你收集整理的Mac OS X下64位汇编与Linux下64位汇编的一些不同的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电子商务系统的设计与实现(九):后端管理
- 下一篇: linux 其他常用命令