Mac OS X下64位汇编与Linux下64位汇编的一些不同
1 首先系統(tǒng)調(diào)用號(hào)大大的不同;mac64和linux32的系統(tǒng)調(diào)用號(hào)也不同(雖然局部可能有相同)
2 mac64的系統(tǒng)調(diào)用號(hào)在:
/usr/include/sys/syscall.h可以查到,但是調(diào)用的時(shí)候其值要加上0x2000000,可以寫一個(gè)宏處理:
%define mk64 0x2000000+使用方式如下:
mov rax,mk64 1 ;exit NO mov rdi,0 ;error_code syscall3 如果在mac64下匯編要與C庫(kù)相鏈接,所有extern符號(hào)名前要加下劃線,包括入口點(diǎn)main:
extern _strerror extern _printf global _main _main:而linux64下匯編和C庫(kù)鏈接的時(shí)候必須去掉符號(hào)前的下劃線。
4 mac里的PIE(參考:http://blog.csdn.net/mydo/article/details/44906109),在直接使用絕對(duì)地址時(shí)會(huì)發(fā)出警告,如想去除警告,必須使用相對(duì)地址:
;mov rbx,addr ;上一條指令要換成下一條 lea rbx,[rel addr] mov rsi,[rbx]5 mac64下不允許將值賦到32位的絕對(duì)地址里去,比如以下指令出錯(cuò):
mov [addr],rax需要強(qiáng)制聲明為64位地址或者改用相對(duì)地址:
mov [qword addr],rax ;ok mov [rel addr],rax ;ok too但linux64下無此限制。
6 mac64和linux64對(duì)系統(tǒng)調(diào)用的C庫(kù)包裝有所不同,尤其是處理系統(tǒng)調(diào)用返回值的時(shí)候;比如mmap調(diào)用,linux64 C庫(kù)貌似不檢查參數(shù),而是依據(jù)syscall自身檢查;而mac64在調(diào)用前會(huì)檢查參數(shù),如果參數(shù)有誤,根本不會(huì)進(jìn)行系統(tǒng)調(diào)用,直接設(shè)置errno,然后返回。再拿mmap來說,如果在mmap C庫(kù)函數(shù)上設(shè)斷點(diǎn),那么在經(jīng)過N次的fast_syscall_stub之后:
-> 0x7fff8c4fc3b5 <+277>: callq 0x7fff8c4fd9e0 ; _dyld_fast_stub_entry(void*, long)才會(huì)進(jìn)入斷點(diǎn),所以要在fast_syscall_stub上設(shè)置條件斷點(diǎn),忽略前面N次的捕獲(我測(cè)試的程序時(shí)或略前面28次),然后會(huì)進(jìn)入kernel動(dòng)態(tài)庫(kù)中的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其對(duì)傳入mmap的參數(shù)進(jìn)行了檢查,如果發(fā)現(xiàn)參數(shù)錯(cuò)誤,不會(huì)調(diào)用真正的__mmap函數(shù),而是設(shè)置錯(cuò)誤碼,然后根據(jù)不同的錯(cuò)誤類型跳至對(duì)應(yīng)的C庫(kù)錯(cuò)誤處理函數(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)鍵的一點(diǎn)是,貌似mac64直接將系統(tǒng)調(diào)用錯(cuò)誤碼通過rax返回,而不像linux64那樣返回的是錯(cuò)誤碼的補(bǔ)碼。所以博文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 暫時(shí)想到這么多不同點(diǎn),未完待續(xù)
總結(jié)
以上是生活随笔為你收集整理的Mac OS X下64位汇编与Linux下64位汇编的一些不同的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电子商务系统的设计与实现(九):后端管理
- 下一篇: OpenTLD相关资料