」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 了解運行時:從 C 語言到現代語言

了解運行時:從 C 語言到現代語言

發佈於2024-11-08
瀏覽:975

Understanding Runtimes: From C to Modern Languages

在現代軟體開發和程式設計時代,術語「運行時」可能具有不同的含義,具體取決於上下文和所討論的語言。我在這裡澄清這些差異,重點關注與 Java 或 Python 等更現代的語言相比,C 語言的運行時如何運作。我打算讓這篇文章專注於初學者程式設計師,因此我將避免深入研究複雜的概念。

什麼是運行時?

從本質上講,運行時是一個程式本身,它讀取並執行開發人員編寫的程式碼。但當一些開發人員使用 C 語言運行時,就會變得混亂。

現代語言運行時

在Java 或Python 等語言中,運行時本身就是一個讀取myfile.js 檔案的程序,這就是為什麼您運行Nodejs 程序,例如:node myfile.js 和v8 引擎(是JavaScript 引擎,它解析並執行JavaScript程式碼。
但是當你執行一個c程式時,你不需要執行c myfile.c,你只需要編譯一次,現在你不再需要gcc了,直接執行它。

C“運行時”

在 C 中,沒有像 Java 或 Python 那樣與程式碼一起運行的單獨程式。相反,通常所說的C“運行時”實際上是在編譯期間添加的一組靜態插入的程式碼和指令。它是最終二進位檔案中包含的最小指令集,用於處理 CPU/作業系統層級的某些必要任務。它處理函數呼叫的堆疊幀創建和拆卸(在彙編中使用 PUSH、POP、CALL、RET 等指令)。即使這一點也可以透過使用內聯彙編提供您自己的 __start 函數來覆蓋,從而使開發人員能夠完全控製程式的入口點和初始化。


void __start() {
// Custom entry point, no standard library initialization
// You have no access to argc and argv here unless you access them manually from registers
// you can create you own custom stack setup, initialization and etc here.

// Exit directly using a syscall
asm("mov $60, %rax; mov $0, %rdi; syscall"); // exit(0) syscall
}


這看起來根本不像運行時,它只是編譯器添加的一些彙編語言程式碼,因此開發人員不必這樣做。

C的權力與責任

在 C 語言中,您可以使用內聯彙編直接調用系統調用,以作業系統通常不允許的方式與內核交互,這就是惡意軟體的創建方式。內聯彙編允許開發人員在 C 程式碼中編寫彙編語言指令。這通常用於性能關鍵的程式碼或存取特定的硬體功能。

C 中的內聯彙編

  • 內嵌彙編允許開發人員在 C 程式碼中編寫組合語言指令。這通常用於性能關鍵的程式碼或存取特定的硬體功能。
  • 它提供了一種直接執行CPU指令的方式。

與內核直接交互

  • 使用內聯彙編,程式設計師可以直接調用系統調用,而無需通過更高層級的函式庫。
  • 例如,我們可以使用內聯彙編為系統呼叫設定適當的參數暫存器,然後觸發它。
  • 由於內聯彙編允許對系統資源進行低階控制,因此它可用於繞過安全機製或直接操縱核心。這就是惡意軟體執行未經授權的操作的方式,例如存取受保護的記憶體、攔截系統呼叫或操縱進程及其記憶體。
  • 惡意軟體可以利用作業系統中的漏洞或使用這些低階互動來執行鍵盤記錄、權限升級或秘密操作等任務。

在linux C中有一個FLAG,允許您直接將檔案資料寫入儲存設備,繞過一些核心的快取機制,稱為O_DIRECT標誌,它與open和write系統呼叫結合使用。此標誌確保資料不會在 RAM 中緩衝或由核心在內核空間中管理,這會直接將資料寫入硬碟,JVM 不允許您這樣做,這只是一個簡單的範例。
這是一個簡單的例子:


asm volatile (
"syscall"
: "=a" (written)
: "0" (1),
"D" (fd),
"S" (buffer),
"d" (BLOCK_SIZE)
: "rcx", "r11", "memory"
);


*注意:*(寫入)是在main() 內部建立的變量,(1) 是寫入的系統呼叫號,(fd) 是檔案將被寫入的位置,即int fs = open("path .log",O_WRONLY; (BLOCK_SIZE) 是另一個變數名稱。它比那個更複雜。

運行時的演變

了解運行時概念多年來的演變非常重要。 70 年代的 C「運行時」與我們在 2000 年代的語言中看到的健壯的運行時環境有很大不同。在討論運行時時,這種演變可能會導致混亂,尤其是在熟悉不同程式設計時代的開發人員之間。

結論

我認為人們現在正在將 1970 年代的運行時與 2000 年代的運行時進行比較,這讓新開發人員與老開發人員感到困惑。
解決特定問題是任何程式語言的主要任務,你不想用C 編寫一個完整的框架來創建API,我們有NodeJS,它很擅長,你不需要用JavaScript 編寫裸機程式碼,因為我們已經有了C 並且它在這方面非常棒。為什麼要重新發明輪子,讓我們用輪子創造一輛神奇的汽車,除非你不想在火星上駕駛它。

版本聲明 本文轉載於:https://dev.to/bossysmaxx/understanding-runtimes-from-c-to-modern-languages-3fkj?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3