簡體   English   中英

32位應用程序如何在64位Linux上進行系統調用?

[英]How do 32-bit applications make system calls on 64-bit Linux?

一些(很多?全部?)64位1 Linux發行版允許通過提供32位和64位庫(包括libc)的並行集合來運行32位應用程序。 因此,32位應用程序可以鏈接到32位庫,並由64位內核運行。

我想知道的32位應用程序如何讓在64位內核的系統調用的機制 我懷疑答案是在libc和/或內核源代碼中的某個地方,但是由於我不知道在哪里看,所以潛入源代碼會很費時間。

還有一個更重要的問題, 是否有任何性能開銷? 2從邏輯上講,來自32位app系統調用的調用必須轉換為64位內部內核環境。 這完成的方式和地點?

1 “32位”= IA-32,“64位”= AMD64
2在你的回答中假設它很重要:)

從用戶空間方面來看,這些機制與在32位本機內核上進行系統調用相同 - 所有用戶模式代碼(包括32位glibc)都以相同的方式工作。

從內核端,用戶空間(例如int 0x80 )的舊IA32入口點被設置為調用ia32_syscall匯編程序例程。 (轉換到內核空間涉及處理器加載內核的代碼段選擇器,這會導致轉換到64位“長”模式)。

然后, ia32_syscall例程將一些參數ia32_syscall ,以匹配x86_64系統調用約定:

movl    %edi,%r8d
.if \noebp
.else
movl    %ebp,%r9d
.endif
xchg    %ecx,%esi
movl    %ebx,%edi
movl    %edx,%edx   /* zero extension */

然后,它使用IA32系統調用號通過表ia32_sys_call_table進行函數調用。 這基本上將IA32系統調用號與本機系統調用實現相匹配(系統調用號在IA32和x86_64之間差別很大)。 該表的第一部分如下所示:

ia32_sys_call_table:
    .quad sys_restart_syscall
    .quad sys_exit
    .quad stub32_fork
    .quad sys_read
    .quad sys_write

對於大多數系統調用,現在可以直接調用x86_64實現 - 比如exit() 對於其他人,比如fork() ,提供了一個正確實現預期IA32語義的包裝器(特別是,如果需要從32位到64位的參數的符號擴展)。

正如您所看到的,內核代碼的開銷很小 - 對寄存器值進行了一些微不足道的修改,對於一些函數,還有一個額外的函數調用。 我不確定加載導致從32位模式轉換到64位模式的代碼段選擇器對於處理器執行的速度比不執行的速度慢 - 請檢查處理器體系結構手冊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM