A. 將一個簡單的匯編語言呢轉換成C語言程序
#include<reg51.h>
#define uchar unsigned char
uchar disdat[8]={0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80};
main()
{
uchar a;
while(1)
{
P2=0xc0;
while(!P3_3)
{
a=0;
if(P0_0){a=1;break;}
if(P0_1){a=2;break;}
if(P0_2){a=3;break;}
if(P0_3){a=4;break;}
if(P0_4){a=5;break;}
if(P0_5){a=6;break;}
if(P0_6){a=7;break;}
if(P0_7)continue;
}
do{
P1_0=0;
P2=disdat[a];
}while(!P3_2)
P1_0=1;
P2=0xff;
}
}
B. 將匯編代碼轉換為c語言
目前的反編譯軟體,只存在將機器指令碼反匯編成匯編代碼,不存在將匯編代碼反編譯成C語言的,因為匯編代碼是低級語言,最接近於機器碼(具體可查看不同硬體平台的技術資料),每條匯編指令都對應一個固定的機器碼,這樣進行反匯編是可行的,而C語言屬於高級語言,編譯器沒有能力將匯編語言翻譯成C或更高級的語言。
C. 怎麼把匯編轉換成C語言
如果 只是簡復單的幾行,可以制把編譯後的exe文件,用系統自帶的debug(windows鍵+R打開 運行窗口 輸入debug 空格 exe的路徑)打開debug後,輸入U可以看到幾行匯編代碼。
如果是源代碼 在vs編譯器中調試運行,菜單上的:調試--窗口--反匯編 可以查看,如果是其他編譯器 仔細找找也帶反匯編的
要資料的話 [天書夜讀-從匯編語言到Windows內核編程].譚文.邵堅磊. 這本書的基礎部分里 有c語言與匯編的轉換
D. 怎樣能將匯編語言轉換成c語言
1、打開IAR FOR STM8工程。
E. 如何將這段匯編語言轉換成C語言
如何將這段匯編語言轉換成C語言?題目分別提供了同一C語言代碼的32位和64位匯編版本:很容易可以得出其源C語言代碼:
int f(int** p){
return (**p=**p+4,*(int*)**p);
}
則函數體的返回值類型是int,參數p的類型是int**,其唯一的語句是return (**p=**p+4,*(int*)**p);
先把結論放在這,節約不想思考的同學的時間,不同編譯器可能會有所不同,lea 0x4(%eax),%ecx指令可能會被編譯器拆開成兩段:mov (%eax),%ecx 和add 0x4,%ecx(對於64位,則是編譯器把lea lea 0x4(%rax),%rcx,拆開成mov (%rax),%rcx 和add 0x4,%rcx,但是效果是一樣的。
根據題目中函數體只有1句代碼的信息,我們至少確定了這個代碼是一個return語句,如此短小的函數當然只需要用到段內跳轉和段內指針,不需要段地址信息,所以指針大小(64位的RIP和32位的EIP)只是偏移量大小,分別為64位(8位元組)和32位(4位元組)。
題目的設問有相當好的引導性,對比查看左邊和右邊的倒數第3個指令,我們可以看出:函數的返回值都是放在eax變數之中,說明返回值的類型大小是4個位元組。而同時,我們知道在C語言中,64位和32位環境下,int類型的大小都是4個位元組,所以第1空的答案不能是只有1位元組的char類型,也不能是在32位環境下大小為4位元組而在64位環境下大小為8位元組的指針類型如char*、int*。綜上,第1空的答案:函數f的返回值類型只能是int。
第2空則是考查C語言函數的參數傳遞,棧式參數傳遞,在call函數f把ip壓入(分別為64位的RIP和32位的EIP)之前,先壓入的是函數的實際參數,其類型暫時不知道,那就得從匯編指令中找出這個信息點:
C語言函數體標志就是:push %ebp→mov %esp,%ebp→函數體內部→pop %ebp→ret(對64位則是:push %rbp→mov %rsp,%rbp→函數體內部→pop %rbp→retq)
兩邊都是同一個簡單的c語句得到的匯編語句(64位和32位),左邊64位的第2、3、4行對應於右邊的第2、3行(64位多用了一個rdi寄存器傳遞參數,可能是編譯器選項不同的緣故,又因為main函數中調用函數f的指令沒有給出,且不一定相同,故不影響判斷)。
兩邊剩下的幾行代碼(左邊2、3、4、5、6、7、8行,右邊2、3、4、5、6、7行)的工作大同小異,從數據流上看(函數體內,對於32位0x8(%ebp)是第一個也是唯一一個參數,對於64位-0x8(%rbp)才是):
*p→eax,*eax→eax,eax+4→ecx(①),*p→edx,ecx→*edx,*eax→eax
可以簡化為:
**p→eax,eax+4→ecx,ecx→**p,***p→eax
再簡化為
**p+4→**p,***p→eax
註:(①)lea 0x4(%eax), %ecx 意思是取有效地址Load Effect Address,相比於mov 0x4(%eax), %ecx使用地址所指向的值*(eax+4)→ecx,lea指令只使用地址的值eax+4→ecx,少做一步。64位也是如此a。
(對於64位則是:
*p→rax,*rax→rax,rax+4→rcx,*p→rdx,rcx→*rdx,*rax→eax
可以簡化為:
**p→rax,rax+4→rcx,rcx→**p,***p→eax
再簡化為
**p+4→**p,***p→eax
)
看到數據流了,C語言語句自然也就呼之欲出了,即return (**p=**p+4,*(int*)**p)。(逗號,運算符的意思是從左到右計算式子,然後返回最後一個)
注意這里的+4指的是4個位元組,而在64位32位中都一樣,於是初步斷定**p是固定大小類型變數,同時返回值是int類型的,故認為它(**p)是int,所以參數p的類型就是int**。