本文目錄一覽:
- 1、C語言與彙編語言
- 2、彙編語言和c語言區別
- 3、如何用彙編實現C語言函數調用
- 4、一個簡單的問題 c語言調用彙編代碼再調用Messagebox函數,求代碼分析
- 5、C語言和彙編語言的區別是什麼?
- 6、實踐,C語言是怎麼變成彙編的
C語言與彙編語言
樓上都不懂。
C相對彙編來說的優勢主要在移植性上和開發效率上。程序執行效率不如彙編。所以如果不關注程序執行效率的話,推薦用C.當然,現在絕大部分的處理器都有C編譯器。
但是為什麼8086上採用彙編語言呢?
最主要的的原因是,8086有足夠多的通用寄存器。
為什麼有足夠多的通用寄存器就不需要用C了呢?
原因在於,你就不需要層層壓棧來控制參數的保存和傳遞,而這在C里都是編譯器為你自動分配的。在C里,對你而言只要知道你定義的變數名就可以,而不需要知道編譯器是如何分配內存單元或者寄存器來存儲你的變數。當你擁有了足夠多的通用寄存器,用彙編做小程序不是更簡單?
彙編語言和c語言區別
彙編語言與C語言的區別:
1、在彙編語言中,為一個處理器編寫的程序不能在另一種類型的處理器上運行。在C語言程序中,程序獨立於處理器類型運行。
2、彙編語言代碼的性能和準確性優於C代碼。
3、C語言必須提供額外的指令來在計算機上運行代碼。
4、彙編語言代碼比C代碼難以理解和調試。
5、 一個或兩個C語言語句擴展為許多彙編語言代碼。
6、彙編語言可以比C別更好地進行通信某些類型的硬體操作只能通過彙編語言執行。
7、在彙編語言中,我們可以直接讀取物理地址上的指針,這在C別是不可能的。
8、在彙編語言中使用位更容易。
9、彙編程序用於在彙編語言中轉換代碼,而編譯器用於在C編譯代碼。
10、C語言的可執行代碼大於彙編語言代碼,因此執行時間較長。
11、由於長的可執行代碼,C程序的效率低於彙編語言程序。
12、與彙編程序員相比,C語言程序員不需要知道處理器中的寄存器等 硬體細節。
13、最C的語言代碼首先自動轉換為彙編代碼。
如何用彙編實現C語言函數調用
1。對於「彙編調用」:
我知道你要調用func,而不是它本身,但如果這個函數比較複雜時是必須用逆向先分析func這個函數,然後再確定參數列表和返回值的……
2。對於你的內聯彙編的代碼:
這裡到底要不要用add %3, %%rsp;還是一個問題,因為要看函數使用的是什麼調用標準,有標準C的,VB的,Pascal的,包括fastcall,stdcall,cdecl等……
3。對於「知道函數參數的起始地址和長度」:
這個的話,除了參數中有字元數組和直接結構體什麼的,所有的基本變數基本都是每8位元組(64位)一個,並且Intel一般都用bigendian的,也就是說,在內存中 01 02 03 04 05 06 07 08 讀入寄存器後會變為: 0x0807060504030201
所以說對於簡單的函數,用8位元組一個參數來做就好了……
而對於有字元數組什麼的就必須用逆向分析了……
這個……只能進行逆向分析了……
反正你知道了函數的地址和長度……
就是你把編譯為機器碼的程序用反編譯工具翻譯成彙編,然後分析一下就好了,C語言的彙編還是比較簡單……
比如這個函數:
int func(int a, int* b) {
// float要用到CPU的FPU,指令記不得,要查下
// 為了簡單就改為int*
printf(“a = %d, b = %d\n”, a, *b);
return a;
}
編譯成機器碼後,反編譯,如果不加優化,一般都會這樣:
(假設函數入口地址為0400000h)
sub_0400000:
push rbp
mov rbp,rsp ; C函數參數度取使用堆棧式
; 參數在內存中這樣: |…| a | b | … |
; 由於是64位,故8位元組對齊
mov rax,[rbp+8] ; rax = *(rbp+8) // 這裡就是 rax = a
push rsi
mov rsi,[rbp+16] ; rsi = *(rbp+16) // rsi = b
; 調用C函數都是這樣堆棧式,最後一個參數最先入棧
push [rsi]
push rax
push “a = %d, b = %d\n” ; 這裡是便於理解,實際上是push這個字元串常量的指針
call printf ; printf(“a = %d, b = %d\n”,rax,*rsi)
add rsp,24 ; 平衡堆棧,用了3個參數,要還原3*8=24位元組,但根據函數類型的不同去平衡,像調用VB的函數就不需要平衡堆棧……
; 還原數據
mov rsp,rbp
pop rsi
pop rbp
; 一般返回數據都用rax裝載
mov rax,[rbp+8] ;rax=a
ret ; return rax
想調用未知參數列表的函數就是把以上過程倒過來,看著彙編把C的代碼寫出來……
破解註冊碼什麼也是這樣玩的……
實際上你可以直接用反編譯的軟體,比如IDA,直接自動分析,它反編譯的雖然是彙編,但參數列表還是大部分都顯示的……
但是,當編譯器加優化大部分情況就必須自己分析了,因為:
int func(int a, int* b) {
printf(“a = %d, b = %d\n”, a, *b);
return a;
}
在優化情況下可能為(直接用寄存器傳遞數據):
sub_040000:
push rdx
mov rdx,rax
push rax
push rbx
push “a = %d, b = %d\n”
call printf
mov rax,rdx
pop rdx
ret
其實像看雪學院有不少這方面的教程……
一個簡單的問題 c語言調用彙編代碼再調用Messagebox函數,求代碼分析
內嵌彙編可以直call函數名調用函數,根本不用這麼折騰。另外其實他獲得函數入口的的方法是錯的,知識碰巧能用而已。
lea edx, [ebp – 04h] 就相當於edx = ebp – 04h彙編寫就是
mov edx, ebp
sub edx, 04h
但是前一種寫法方便,執行效率也高。
三個push是把MessageBox的參數推進棧。類似於C里寫MessageBox(edi, edx, edx, edi)(因為前面還有一個push edi)。因為edi是0,edx是那個Hi,所以其實就是MessageBox(0, “Hi!”, “Hi!”, 0)。
C語言和彙編語言的區別是什麼?
區別如下:
(1)兩者編譯組成不同。彙編語言是將由0、1組成的機器語言用具有簡單語義的英文代碼表示,而C語言不但將許多相關的機器指令合成為單條指令,並且去掉了與具體操作有關但與完成工作無關的細節,例如使用堆棧、寄存器等。
(2)兩者被計算機識別的路徑不同。彙編語言通常用於對硬體的直接操控。而且C語言所編製的程序不能直接被計算機識別,必須經過轉換才能被執行。
(3)兩者用處不同。彙編語言通常用在程序中最核心的、控制硬體的代碼,一方面是安全,另一方面提高運行速度。而C語言通常用在計算機外用功能上。
(4)兩者學習難易程度不同。彙編語言所需要的編繪知識很多很複雜,經常被開發者使用。而C語言是一門很簡單方便的語言,編程者也就不需要有太多的專業知識。
計算機語言(Computer Language)指用於人與計算機之間通訊的語言。計算機語言是人與計算機之間傳遞信息的媒介。計算機系統最大特徵是指令通過一種語言傳達給機器。計算機語言從低級到高級可以分為:
(1)機器語言,即由0、1組成的機器硬體可以識別的語言;
(2)低級語言,即彙編語言
(3)中級語言,如C語言
(4)高級語言,如C++,JAVA,C#等。
擴展資料:
如今通用的編程語言有兩種形式:彙編語言和高級語言。
彙編語言和機器語言實質是相同的,都是直接對硬體操作,只不過指令採用了英文縮寫的標識符,容易識別和記憶。源程序經彙編生成的可執行文件不僅比較小,而且執行速度很快。
高級語言是絕大多數編程者的選擇。和彙編語言相比,它不但將許多相關的機器指令合成為單條指令,並且去掉了與具體操作有關但與完成工作無關的細節,例如使用堆棧、寄存器等,這樣就大大簡化了程序中的指令。同時,由於省略了很多細節,編程者也就不需要有太多的專業知識。
高級語言主要是相對於低級語言而言,它並不是特指某一種具體的語言,而是包括了很多編程語言,如流行的vb、vc、foxpro、delphi等,這些語言的語法、命令格式都各不相同。
高級語言所編製的程序不能直接被計算機識別,必須經過轉換才能被執行,按轉換方式可將它們分為兩類:解釋類和編譯類。
參考資料:計算機語言_百度百科
實踐,C語言是怎麼變成彙編的
c語言未必會經歷彙編語言這一環節,準確的說,c語言經歷編譯器(必須),鏈接器(某種程度上非必須)的處理,成為可執行代碼(一般是二進位代碼)。
而彙編也許是目前多數編譯器提供的中間環節(vc,vs都提供在調試運行下使用反彙編的功能),因為對於彙編語言來說,進一步編譯成機器語言的難度很低,只需查找有限的彙編指令對應的編碼,如MOV,ADD等,具體編碼與機器有關。
而你說的c語言變成彙編這一過程,正是編譯器的核心工作,也是最為困難的。需要對你的程序(本質上是一個超長的字元串)做分割,詞法分析,語法分析,最後翻譯成彙編。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/302770.html