C语言MIPS指令翻译成机器码,计算机指令
在軟硬件接口中,CPU幫我們做了什么?
從硬件角度來看,?CPU就是一個(gè)超大規(guī)模集成電路,通過電路實(shí)現(xiàn)了加法,乘法乃至各種各樣的處理邏輯。
從軟加工程師的角度來講,CPU就是一個(gè)執(zhí)行各種計(jì)算機(jī)指令(Instruction?Code)的邏輯機(jī)器。這里的計(jì)算機(jī)指令,就好比一門CPU能夠聽懂的語言,我們把它叫做機(jī)器語言(Machine?Language)
不同的CPU能夠聽懂的語言不太一樣。比如我們個(gè)人電腦用的Intel的CPU,蘋果手機(jī)用的是ARM的CPU。類似這樣兩種CPU各自支持的語言,就是兩組不同的計(jì)算機(jī)指令集(Instruction?set)
一個(gè)計(jì)算機(jī)程序,不可能只有一條指令,而是由成千上萬條指令組成的。但是CPU里不能一直放著所有指令,所以計(jì)算機(jī)程序平時(shí)是存儲(chǔ)在存儲(chǔ)器中的。這種指令存儲(chǔ)在存儲(chǔ)器里面的計(jì)算機(jī),我們就叫做存儲(chǔ)程序型計(jì)算機(jī)
從編譯到匯編,代碼怎么變成機(jī)器碼?
//test.c
intmain()
{int a = 1;int b = 2;
a= a +b;
}
要讓這段程序在一個(gè)Linux操作系統(tǒng)上跑起來,我們需要把整個(gè)程序翻譯成一個(gè)匯編語言(ASM,Assembly?Language)的程序,這個(gè)過程我們一般叫編譯(Compile)成好匯編代碼。
針對(duì)匯編代碼,我們可以再用匯編器(Assembler)翻譯成機(jī)器碼(Machine?Code)。這些機(jī)器碼由“0”和“1”組成的機(jī)器語言表示。這一條條機(jī)器碼,就是一條條的計(jì)算機(jī)指令。這樣一串串的16進(jìn)制數(shù)字,就是我們CPU能夠真正認(rèn)識(shí)的計(jì)算機(jī)指令
在一個(gè)Linux操作系統(tǒng)上,我們可以簡單地使用gcc和objdump這樣兩條命令,把對(duì)應(yīng)的匯編代碼和機(jī)器碼都打印出來。
[learning_log@localhost 桌面]$ gcc -g -c text.c
[learning_log@localhost 桌面]$ objdump-d -M intel -S text.o
text.o: 文件格式 elf64-x86-64Disassembly of section .text:0000000000000000 :intmain()
{0: 55push rbp1: 48 89e5 mov rbp,rspint a = 1;4: c7 45 fc 01 00 00 00 mov DWORD PTR [rbp-0x4],0x1
int b = 2;
b: c745 f8 02 00 00 00 mov DWORD PTR [rbp-0x8],0x2a= a +b;12: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8]15: 01 45 fc add DWORD PTR [rbp-0x4],eax
}18: 5d pop rbp19: c3 ret
可以看到左側(cè)一堆數(shù)字,這些就是一條條機(jī)器碼;右邊有一系列的push、mov、add、pop等,這些就是對(duì)應(yīng)的匯編代碼。一行C語言代碼,有時(shí)候?qū)?yīng)一條機(jī)器碼和匯編代碼,有時(shí)候則是對(duì)應(yīng)兩條機(jī)器碼和匯編代碼。匯編代碼和機(jī)器碼之間是一一對(duì)應(yīng)的。
從高級(jí)語言到匯編代碼,再到機(jī)器碼,就是一個(gè)日常開發(fā)程序,最終變成了CPU可以執(zhí)行的計(jì)算機(jī)指令的過程。
解析指令和機(jī)器碼
常見的指令可以分為五大類。
第一類是算術(shù)類指令。我們的加減乘除,在CPU層面,都會(huì)變成一條條算術(shù)類指令。
第二類是數(shù)據(jù)傳輸類指令。給變量賦值,在內(nèi)存里讀寫數(shù)據(jù),用的都是數(shù)據(jù)傳輸類指令。
第三類是邏輯類指令。邏輯上的與或非,都是這一類指令。
第四類是條件分支類指令。日常我們寫的“if/else”,其實(shí)都是條件分支類指令。
最后一類是無條件跳轉(zhuǎn)指令。寫一些大一點(diǎn)的程序,我們常常需要寫一些函數(shù)或者方法。再調(diào)用函數(shù)的時(shí)候,其實(shí)就是發(fā)起了一個(gè)無條件跳轉(zhuǎn)指令。
我們說過,不同的CPU有不同的指令集,也就對(duì)應(yīng)著不同的匯編語言和不同的機(jī)器碼。為了方便你快速理解這個(gè)機(jī)器碼的計(jì)算方式,我們選用最簡單的MIPS指令集,來看機(jī)器碼是如何生成的。
MIPS的指令是一個(gè)32位的整數(shù),高6位叫操作碼(Opcode),也就是代表這條指令具體是一條什么樣的指令,剩下的26位有三種格式,分別是R、I、J。
R指令是一般用來做算術(shù)和邏輯操作,里面有讀取和寫入數(shù)據(jù)的寄存器的地址。如果是邏輯位移操作,后面還有位移操作的位移量,而最后的功能碼,則是在前面的操作碼不夠的時(shí)候,擴(kuò)展操作碼表示對(duì)應(yīng)的具體指令的。
I指令,則通常是用來數(shù)據(jù)傳輸,條件分支,以及在運(yùn)算的時(shí)候使用的并非變量還是常數(shù)的時(shí)候。這個(gè)時(shí)候,沒有了位移量和操作碼,也沒有了第三個(gè)寄存器,而是把這三部分直接合并成一個(gè)地址值或者常數(shù)。
J指令就是一個(gè)跳轉(zhuǎn)指令,高6位之外的26位都是一個(gè)跳轉(zhuǎn)后的地址。
add $t0,$s2,$s1
對(duì)應(yīng)的MIPS指令里的opcode是0,rs代表第一個(gè)寄存器s1的地址是17,rt代表第二個(gè)寄存器s2的地址是18,rd代表目標(biāo)的臨時(shí)寄存器t0的地址,是8。因?yàn)椴皇俏灰撇僮?#xff0c;所以位移量是0.把這些數(shù)字拼在一起,就變成了一個(gè)MIPS的加法指令。
為了讀起來方便,我們一般把對(duì)應(yīng)的二進(jìn)制數(shù),用16進(jìn)制表示,也就是0X02324020。這個(gè)數(shù)字也就是這條指令對(duì)應(yīng)的機(jī)器碼。
如果想要對(duì)日常使用的Intel?CPU的指令集有所了解,可以參看《計(jì)算機(jī)組成與設(shè)計(jì):軟/硬件借口》第5版的2.17小節(jié)。
總結(jié)
以上是生活随笔為你收集整理的C语言MIPS指令翻译成机器码,计算机指令的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 【微信支付】(亲测可用)对接app微信支
 - 下一篇: PC老照片智能一键修复软件