從沒想過有人會把這兩個毫不相關的概念混爲一談,可招聘時還真就碰到問內聯答內嵌的情況。上網一查,原來內嵌彙編也常被叫內聯彙編,中文表述IT名詞時真就這麼乏力麼?蹩腳的撞名一個接一個。
內聯函數即inline函數,其作用是“建議”編譯器展開函數,不是一定展開,除非設置強制內聯(如gcc的__attribute__((always_inline)))。展開即把函數代碼插入被調用位置,可以節省函數調用的進出棧開銷,但會增加代碼量。所以一般短小函數適合內聯展開,而大函數展開會大大增加指令內存,還可能影響指令cache命中率,得不償失。
除inline外static也有類似作用:編譯器會傾向於展開static修飾的小函數,且static能把函數作用域限制在單個源文件內,因此單個源文件內定義和調用的inline函數多用static或static inline代替;而多個源文件中被調的函數,則用inline展開。
內嵌彙編(內聯彙編)是在高級語言中嵌入彙編的一種語法,這個功能可以把一些C/C++無法表達的指令或者一些編譯器無法自動生成的指令直接插入C/C++代碼中,在軟件優化/繞過編譯器實現特殊功能/底層驅動或操作系統移植等場合很有用。不同編譯器有各自的內嵌彙編語法標準,且相比真正的彙編指令,內嵌彙編無論從語法格式和指令新式上都有很大區別。如GCC的內嵌彙編基本語法:
__asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr)); 而ads中的內嵌彙編又是下面的格式: __asm{ smull tmp, ret.hi, a, b; }
這些內嵌彙編並非直接送給assembler,而要先經complier處理,得到真正彙編指令,再交給assembler。
總結:內聯函數由C關鍵字inline/static提示,所有C編譯器都支持;內嵌彙編僅是編譯器的一種補充手段,是否支持以及怎樣支持要看具體編譯環境。