日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Y86-64指令集体系结构

發布時間:2024/1/1 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Y86-64指令集体系结构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

前言:

1.程序員可見狀態

?2.Y86-64指令

3.指令編碼

movq指令

整數操作指令

跳轉指令

條件傳送指令

call和ret指令?

push和pop指令?

halt和nop指令

4.Y86-64異常

5.Y86-64程序


前言:

本章內容是筆者學習csapp的一些讀書筆記,其中大部分內容來自原書,并加入了一些自己的注釋

指令系統是計算機軟件和硬件交互的接口,由于x86指令集相對復雜,書中定義了一個簡單的指令集 “Y86-64” ,能夠滿足一個處理器對于指令集的基本需求

1.程序員可見狀態

在這里,“程序員” 既可以是用匯編代碼寫程序的人,也可以是產生機器級代碼的編譯器

程序員的可見狀態是指:Y86-64中的每條指令都會讀取或者修改處理器狀態的某些部分,如程序寄存器、條件碼、程序計數器(PC)、內存以及程序狀態等等

? 對于程序寄存器,相比于x86,%rsp也是被用作棧指針,而Y86-64指令集體系結構中少了程序寄存器%r15,這么做的目的降低編碼的復雜度,這一點會在后面提及

? 條件碼有3個,分別是ZF、SF、OF (有關條件碼的內容可以參考)條件碼、條件控制和條件傳送_七月不遠.的博客-CSDN博客https://blog.csdn.net/weixin_58165485/article/details/123466697?spm=1001.2014.3001.5502? 程序計數器(PC)存放當前正在執行指令的地址 (注意:是地址而并非內容)

? 程序狀態碼表明這條指令是否正常運行


?2.Y86-64指令

相比于x86-64指令集,Y86-64指令集做了相應的簡化:

??movq指令

?x86-64中的movq指令在這里被分為四種,分別是:

Source operandDestination operand
irmovqImmediateRegister
rrmovqRegisterRegister
rmmovqRegisterMemory
mrmovqMemoryRegister

指令的第一個字母表示源操作數的類型,第二個字母表示目的操作數的類型,源操作數可以是立即數(i)?,寄存器(r),內存(m),目的操作數可以是寄存器(r)和內存(m)

  • irmovq指令表示將一個立即數存進一個寄存器中?
  • rrmovq指令表示將一個寄存器中的值存進一個寄存器
  • rmmovq指令表示將一個寄存器中的值存進一個內存地址所對應的內存
  • mrmovq指令表示將一個內存中的值存進一個寄存器

值得注意的是,我們不能:

  • 從一個內存地址直接傳送到另一個內存地址,形如mmmovq是不被允許的
  • 將立即數直接傳送到內存,形如immovq是不被允許的?

? 整數操作指令

Y86-64定義了4個整數操作指令,分別是加(addq),減(subq),與(andq),異或(xorq)?

  • 只能對寄存器數據進行操作 (這點很重要,x86-64中還允許對內存進行操作)
  • 會設置條件碼

? 跳轉指令?

跳轉指令形如 jXX,Y86-64定義了7個跳轉指令,分別是:

指令跳轉條件描述
jmp1直接跳轉
jle(SF ^ OF) | ZF小于或等于 (有符號 <=)
jlSF ^ OF小于 (有符號 <)
jeZF相等 / 零
jne~ZF不相等 / 非零
jge~(SF ^ OF)大于或等于(有符號 >=)
jg~(SF ^ OF) & ~ZF大于(有符號 >)

根據分支指令的類型和條件代碼的設置來選擇分支?

? 條件傳送指令?

有6個條件傳送指令,形如comvXX:cmovle,cmovl,cmove,cmovne,cmovge,cmovg?

指令格式和rrmovq一樣,但只有滿足條件碼組合時才發生傳送?

? call指令和ret指令

  • call指令的作用是將返回地址入棧,然后跳到目的地址
  • ret指令從這樣的調用中返回

? push指令和pop指令

分別實現入棧和出棧,依靠%rsp來實現?

? halt指令?

halt指令會停止指令的執行,導致處理器停止,并將狀態碼設置為HLT?


3.指令編碼

對于每條指令,Y86-64規定需要1~10個字節不等的編碼長度,如ret指令只需要1個字節就能完成編碼,而irmovq需要10個字節來完成編碼

每條指令的第一個字節表明了指令的類型,它相當于我們的身份證,前六位指明了你所在的地址,而這個字節分為兩個部分,每個部分占4個比特位,高4位表示指令代碼 (icode),第4位表示指令功能 (ifun),下面會有詳細介紹

當指令中有寄存器類型的操作數時,會在后面附加一個字節稱為寄存器指示符字節,用來顯示地給出將要操作地寄存器ID

Y86-64對于15個程序寄存器都給了一個ID,稱為寄存器標識符(register ID)?

數字寄存器名稱數字寄存器名稱
0%rax8%r8
1%rcx9%r9
2%rdxA%r10
3%rbxB%r11
4%rspC%r12
5%rbpD%r13
6%rsiE%r14
7%rdiF無寄存器

相比于x86-64省略掉寄存器%r15,是為了滿足編碼地簡便性,我們可以用4個比特位來描述所有寄存器類型,從0000~1111剛好16個數,而不需要再多用一個比特位來保存17種情況

下面介紹每種指令的編碼形式:?

movq指令

🔰

以rrmovq為例,rrmovq指令是將一個寄存器的值傳送到另一個寄存器中,其編碼有兩個字節長度

第一個字節是 2 0 ,2表示指令代碼,0表示指令功能,當處理器拿到的指令形式為2 0 rA rB時,首先讀到 2 0,處理器知道了這是兩個寄存器之間傳送指令,寄存器指示符字節給出了 rA,rB,指明了即將用到地兩個寄存器ID,因此處理器就會根據這條編碼,將 rA 的值傳送到 rB 中

?🔰

對于irmovq,它表示將一個立即數傳送到寄存器中,其編碼長度有10個字節?

3 0代表的是irmovq,處理器讀到3 0便知道要將一個立即數傳到寄存器,但是在這個過程中只有1個寄存器作為目的操作數被用到,因此在寄存器指示符字節源操作數中是F,表明不需要寄存器,而在后面的8字節中保存的就是這個立即數V,處理器將V傳送到寄存器 rB 中

🔰

rmmovq和mrmovq中的8字節常數字是一個地址偏移量,表明將內存引用的地址是rB內的地址+偏移量D?

整數操作指令

之前已經說過,整數操作指令只能對兩個寄存器中的數據進行操作,因此,只需要2個字節就能完成編碼

  • 第一個字節 6 fn?,前4位 (6) 指出這是一個整數操作符,后4位(fn)則是指令功能位

? ? ? fn = 0 1 2 3分別對應四種規定的整數運算?

  • 第二個字節是寄存器指示符字節,指明了即將操作的兩個寄存器ID

因此,類似 6 1 2 3這種編碼意思就是將寄存器 %rdx 中的值減去寄存器 %rbx 中的值,并把返回結果保存到?%rdx中

跳轉指令

和整數操作指令類似,跳轉指令也有功能之分,ifun部分分為0~7:

?后面的Dest指明了要跳轉的地址,如果滿足條件,則下一條指令跳轉到這個絕對地址執行

注意:分支指令和調用指令的目的一定是一個絕對地址,而不像IA32中那樣使用PC相對尋址?

條件傳送指令

和跳轉指令類似,條件傳送指令的fn分為0~6:

當fn = 0時,代表無條件傳送,也就是我們之前提到的rrmovq

其余的fn都是需要條件碼滿足條件時,才更新目的寄存器的值?

call和ret指令?

call和ret指令分別實現函數調用和返回,其中

  • call指令需要9個字節來編碼,除了第一個字節外,剩下部分是一個絕對地址指向調用函數的地址?
  • ret指令返回的地址存儲在棧上,故不需要在指令中給出

push和pop指令?

push和pop指令分別實現入棧和出棧的操作,注意的是即使編碼中只有rA一個目的操作數,但實際上這兩條指令也同時調用了%rsp(棧指針)?

halt和nop指令

  • halt:停止指令的執行
  • nop:執行一個空操作?

練習:rmmovq %rsp,0x123456789abcd(%rdx)?進行編碼?

rmmovq的第一個字節是40,%rsp的編號是4,%rdx編號是2,因此前兩個字節編碼是4042,而rmmovq的編碼規則將地址偏移量放在后8字節的常數字中,故在小端機器上的編碼為:

4042cdab896745230100?


4.Y86-64異常

對于Y86-64來說,程序員可見狀態包括了狀態碼Stat,其可能的值如下:

名稱含義
1AOK正常操作
2HLT遇到器執行halt指令
3ADR遇到非法地址
4INS遇到非法指令


5.Y86-64程序

對于下面代碼,用sum函數計算一個整數數組的和:

long sum(long* start, long count) {long sum = 0;while (count) {sum += *start;start++;count--;}return sum; }

x86-64(由GCC產生)和Y86-64匯編代碼如下:?

我們可以很清楚地看到一些差別:

  • Y86-64在第2~3行將兩個數加載到兩個寄存器中,因為不允許在整數操作中使用立即數,只能使用寄存器
  • Y86-64在第8~9行先將一個數從內存中取到寄存器中,再完成加法,因為不允許在內存的數與寄存器的數相加

總結

以上是生活随笔為你收集整理的Y86-64指令集体系结构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。