《匯編語言:基于X86處理器》第12章 浮點數處理與指令編碼(2)

Intel X86架構數據的運算主要由通用寄存器處理,但浮點數例外,浮點數的運算由專門的FPU寄存器處理。二進制浮點數由三部分組成:符號,有效數字和階碼。這些格式都出自由IEEE組織制定的標準754-1985:以下是三種浮點數的格式:
●32位單精度數值包含1位符號、8位階碼,以及23位有效數字的小數部分。
●64位雙精度數值包含1位符號、11位階碼,以及52位有效數字的小數部分。
●80 位擴展雙精度數值包含1位符號、16 位階碼,以及 63 位有效數字的小數部分。
本篇介紹浮點數處理與指令編碼。

12.3 x86指令編碼

若要完全理解匯編語言操作碼和操作數,就需要花些時間了解匯編指令翻譯成機器語言的方法。由于Intel 指令集使用了豐富多樣的指令和尋址模式,因此這個問題相當復雜。首先以實地址模式的8086/8088為例來說明,之后,再展示32 位處理器帶來的變化。

Intel 8086處理器是第一個使用復雜指令集計算機(Complex Instruction Set Computer CISC)設計的處理器。這種指令集中包含了各種各樣的內存尋址、移位、算術運算、數據傳送和邏輯操作。與RISC(精簡指令集計算機,Reduced Instruction Set Computer)指令相比,Intel 指令在編碼和解碼方面有些復雜。指令編碼(encode)是指將匯編語言指令及其操作數轉換為機器碼。指令解碼(decode)是指將機器指令轉換為匯編語言。對 Intel 指令編碼和解碼的逐步解釋至少將有助于喚起對MASM 作者們辛苦工作的理解和欣賞。

12.3.1 指令格式

一般的x86機器指令格式(圖12-6)包含了一個指令前綴字節、操作碼、Mod R/M 字節、伸縮索引字節(SIB)、地址位移和立即數。指令按小端順序存放,因此前綴字節位于指令的起始地址。每條指令都有一個操作碼,而其他字段則是可選的。少數指令包含了全部字段,平均來看,絕大多數指令都有2個或3個字節。下面是對指令字段的簡介:

●指令前綴 覆蓋默認操作數大小。

●操作碼 (操作代碼)指定指令的特定變體。比如,按照使用的參數類型,指令 ADD有 9種不同的操作碼。

●Mod R/M 字段指定尋址模式和操作數。符號“R/M”代表的是寄存器和模式。表12-18列出了Mod字段,表12-19給出了當Mod=10b時16 位應用程序的R/M 字段。

●伸縮索引字節 (scale indexbyte,SIB)用于計算數組索引偏移量。

●地址位移 字段保存了操作數的偏移量,在基址-偏移量或基址-變址-偏移量尋址模式中,該字段還可以與基址或變址寄存器相加。

●立即數 字段保存了常量操作數。

表12-18 Mod字段取值

Mod

位移

00

DISP=0,位移低半部分和高半部分都無定義(除非r/m=110)

01

DISP=位移低半部分符號擴展到16位,位移高半部分無定義

10

DISP=位移高半部分和低半部分都有效

11

R/M 字段包含的是寄存器編號

表12-19 16位R/M字段取值(Mod=10)

R/M

有效地址

R/M

有效地址

000

[BX+SI]+D16

100

[SI]+D16

001

[BX+DI]+D16

101

[DI]+D16

010

[BP+SI]+D16

110

[BP]+D16

011

[BP+DI]+D16

111

[BX]+D16

D16表示偏移量是16位的。

12.3.2 單字節指令

沒有操作數或只有一個隱含操作數的指令是最簡單的指令。這種指令只需要操作碼字段,字段值由處理器的指令集預先確定。表12-20列出了幾個常見的單字節指令。在這些指令中,INCDX指令好像是不應該出現的,它出現的原因是:指令集的設計者決定為某些常用指令提供獨特的操作碼。其結果是,為了代碼量和執行速度要對寄存器增量操作進行優化。

表12-20 單字節指令

指令

操作碼

指令

操作碼

AAA

37

LODSB

AC

AAS

3F

XLAT

D7

CBW

98

INC DX

42

12.3.3 立即數送寄存器

立即操作數(常數)按照小端順序(起始地址為最低字節)添加到指令。首先關注的是立即數送寄存器指令,暫不考慮內存尋址的復雜性。將一個立即字送寄存器的MOV指令的編碼格式為:B8+rw dw,其中操作碼字節的值為B8+rw,表示將一個寄存器編號(0~7)與B8相加;dw為立即字操作數,低字節在低地址。(表12-21列出了操作碼使用的寄存器編號。)下面例子中出現的所有數值都為十六進制。

表12-21 寄存器編號(8/16位)

寄存器

編號

寄存器

編號

AX/AL

0

SP/AH

4

CX/CL

1

BP/CH

5

DX/DL

2

SI/DH

6

BX/BL

3

DI/BH

7

示例: PUSH CX 機器指令為51。編碼步驟如下:

1)帶一個16位寄存器操作數的PUSH指令編碼為50。

2)CX的寄存器編碼為1,因此1+50得到操作碼為51。

示例: MOV AX,1 機器指令為B8 01 00(十六進制)。編碼過程如下:

1)立即數送16位寄存器的操作碼為 B8。

2)AX的寄存器編號為0,將0加上B8(參見表12-21)。

3)立即操作數(0001)按小端順序添加到指令(01,00)。

示例: MOV BX,1234h 機器指令為BB 34 12。編碼過程如下:

1)立即數送16位寄存器的操作碼為B8。

2)BX 的寄存器編號為3,將3加上 B8 得到操作碼BB。

3)立即操作數字節為34 12。

從實踐的角度出發,建議手動匯編一些MOV立即數指令來提高能力,然后通過MASM的源列表文件中的生成代碼來檢查匯編結果。

完整代碼測試筆記

;12.3.3.asm         12.3.3 立即數送寄存器
;將一個立即字送寄存器的MOV指令的編碼格式為:B8+rw dw,其中操作碼字節的值為B8+rw,
;表示將一個寄存器編號(0~7)與B8相加;dw為立即字操作數,低字節在低地址。INCLUDE Irvine32.inc.code
main PROC;push指令編碼為50, DX的寄存器編碼為2,因此2+50得到操作碼52push dx;立即數送16位寄存器的操作碼為B8,DX的寄存器編號為2,相加得到操作碼BA;立即操作數22h按小端順序添加到指令(22 00),所以機器碼為 BA 22 00mov dx, 22h;立即數送16位寄存器的操作碼為B8,CX的寄存器編號為1,相加得到操作碼B9;立即操作數1234h按小端順序添加到指令(34 12),所以機器碼為 B9 34 12mov cx, 1234hINVOKE ExitProcess, 0
main ENDP
END main

查看反匯編:

12.3.4 寄存器模式指令

在使用寄存器操作數的指令中,ModR/M字節用一個3位的標識符來表示寄存器操作數。表12-22列出了寄存器的位編碼。操作碼字段的位0用于選擇8位或16位寄存器1表示16位寄存器,0表示8位存器。

表12-22 Mod R/M字段標識寄存器

R/M

寄存器

R/M

寄存器

000

AX or Al

100

SP or AH

001

CX or CL

101

BP or CH

010

DX or DL

110

SI or DH

011

BX or BL

111

DI or BH

比如,MovAx,Bx的機器碼為89D8。寄存器送其他操作數的16位MOV指令的Intel編碼為89r,其中/r表示操作碼后面帶一個Mod R/M字節。Mod R/M字節有三個字段(mod、reg和r/m)。例如,若 Mod R/M 的值為D8,則它包含如下字段:

mod

reg

r/m

11

011

000

●6~7是mod字段,指定尋址模式。mod字段為11表示r/m字段包含的是一個寄存器編號。

●位3~5是reg字段,指定源操作數。在本例中,BX就是編號為011的寄存器。

●位0~2是r/m字段,指定目的操作數。本例中,AX是編號為000的寄存器。

表12-23 列出了更多使用8位和16位寄存器操作數的例子,

表 12-23 MOV 指令編碼和寄存器操作數的示例

指令

操作碼

mod

reg

r/m

mov ax, dx

8B

11

000

010

mov al,dl

8A

11

000

010

mov cx,dx

8B

11

001

010

mov cl,dl

8A

11

001

010

12.3.5 處理器操作數大小前綴

現在將注意力轉回到x86處理器(IA-32)的指令編碼。有些指令以操作數大小前綴開始,覆蓋了其修改指令的默認段屬性。問題是,為什么有指令前綴?在編寫8088/8086 指令集時,幾乎所有 256 個可能的操作碼都用于處理帶有8位和 16 位操作數的指令。當 Intel 開發32位處理器時,就需要想辦法發明新的操作碼來處理32位操作數,而同時還要保持與之前處理器的兼容性。對于面向 16 位處理器的程序,所有使用 32位操作數的指令都添加一個前綴字節。對于面向 32 位處理器的程序,默認為 32 位操作數,因此所有使用 16 位操作數的指令添加一個前綴字節。8 位操作數不需要前綴。

示例:16位操作數 現在對表 12-23 中的 MOV 指令進行匯編,以此為例來看看在16位模式下前綴字節是如何起作用的。.286 偽指令指明編譯代碼的目標處理器,確保不使用32位寄存器。下面的每條MOV指令都給出了其指令編碼:

.model small
.286
.stack 100h
.code
main PROCmov ax, dx				;8B C2mov al, dl				;8A C2

現在對32位處理器匯編相同的指令,使用.386 偽指令,默認操作數為 32 位。指令將包括16 位和 32 位操作數。第一條MOV指令(EAX、EDX)使用的是32 位操作數,因此不需要前綴。第二條MOV(AX、DX)指令由于使用的是16位操作數,因此需要操作數大小前綴(66):

.model small
.386
.stack 100h
.code
main PROCmov eax, edx			;8B C2mov ax, dx				;66 8B C2mov al, dl				;8A C2

12.3.6 內存模式指令

如果 Mod R/M 字節只用于標識寄存器操作數,那么 Intel 指令編碼就會相對簡單。實際上,Intel 匯編語言有著各種各樣的內存尋址模式,這就使得Mod R/M 字節編碼相當復雜。(指令集的復雜性是RISC設計支持者常見的批評理由。

Mod R/M 字節正好可以指定256 個不同組合的操作數。表 12-24 列出了Mod 00 時的Mod R/M字節(十六進制)。(完整的表格參見《Intel 64and IA-32 Architectures SoftwareDeveloper's Manual》,卷2A。)Mod R/M 字節編碼的作用如下:Mod 列中的兩位指定尋址模式的集合。比如,Mod 00 有 8 種可能的 R/M 數值(000b~111b),有效地址列給出了這些數值標識的操作數類型。

假設想要編碼MOV AX,[SI],Mod位為00b,R/M位為100b。從表12-19可知 AX的寄存器編號為000b,因此完整的Mod R/M 字節為00 000 100b 或04h:

mod

reg

r/m

00

000

100

十六進制字節 04 在表12-24 的AX列第5 行。

MOV [SI],AL 的Mod R/M 字節還是一樣的(04h),因為寄存器AL 的編號也是000。現在對指令MOV [SI],AL進行編碼。8 位寄存器的傳送操作碼為88。Mod R/M 字節為04h,則機器碼為88 04。

MOV 指令示例

表12-25列出了8位和16位MOV指令所有的指令格式和操作碼。表 12-26 和表 12-27給出了表 12-25 中縮寫符號的補充信息。手動匯編 MOV指令時可以用這些表作為參考。(更多細節請參閱Intel 手冊。)

表12-28列出了更多的MOV指令,這些指令能手動匯編,且可以與表中的機器代碼比較。假設myWord的起始地址偏移量為0102h

12.3.7 本節回顧

1.寫出下列 MOV 指令的操作碼:

.data
myByte BYTE ?
myWord WORD ?
.codemov ax, @datamov ds, ax					;a. 8Emov ax, bx					;b. 8Bmov bl, al					;c. 8Amov al, [si]				;d. 8Amov myByte, al			    ;e. A2mov myWord, ax			    ;f. A3

2.寫出下列 MOV 指令的 Mod R/M 字節:

.data
array WORD 5 DUP(?)
.codemov ax, @datamov ds, ax					;a. D8mov dl, bl					;b. D3mov bl, [di]				;c. 1Dmov ax, [si+2]				;d. 44mov ax, array[si]			;e. 84mov array[di], ax			;f. 85

12.4 本章小結

二進制浮點數由三部分組成:符號、有效數字和階碼。Intel處理器使用了三種浮點數一進制存儲格式,這些格式都出自由IEEE組織制定的標準754-1985:二進制浮點數運算:

●32位單精度數值包含1位符號、8位階碼,以及23位有效數字的小數部分。

●64位雙精度數值包含1位符號、11位階碼,以及52位有效數字的小數部分。

●80 位擴展雙精度數值包含1位符號、16 位階碼,以及 63 位有效數字的小數部分。

若符號位為 1,則數值為負數;若該位為 0,則數值為正數。

浮點數的有效數字由小數點左右兩邊的十進制數字構成。

并非所有處于0到1之間的實數都可以在計算機內表示為浮點數,其原因是有效位的個數是有限的。

規格化有限數是指,能夠編碼為0到無窮之間的規格化實數的所有非零有限數值。正無窮(+∞)代表最大正實數,負無窮(-∞)代表最大負實數。NaN 為位模式,不表示有效浮點數。

Intel 8086 處理器被設計為只處理整數運算,因此 Intel 提供了獨立的 8087 浮點數協處理器(floating-pointcoprocessor)芯片與8086一起置于計算機的主板上。隨著Intel486的出現,浮點操作被整合到主 CPU 內,稱為浮點單元(FPU)。

FPU 有 8 個相互獨立的可尋址的 80 位寄存器,分別命名為RO~R7,它們構成一個寄存器堆棧。在計算時,浮點操作數以擴展實數的形式保存在FPU 堆棧中。內存操作數也可以用于計算。FPU 在把算術運算操作的結果保存到內存時,會把結果轉換為下述格式之一:整數、長整數、單精度數、雙精度數或者 BCD 碼。

Intel 浮點指令助記符用字母F開始,以區別于 CPU 指令。指令的第二個字母(通常為B或I)表示如何解釋內存操作數:B表示為操作數為二進制編碼的十進制數(BCD 碼),I表示操作數為二進制整數。如果沒有指定,那么內存操作數就假設為實數格式。

Intel 8086 是第一個使用復雜指令集計算機(CISC)設計的處理器。其龐大的指令集包含了各種各樣的內存尋址、移位、算術運算、數據傳送和邏輯操作。

指令編碼是指把匯編語言指令及其操作數轉換為機器碼。指令解碼是指將機器碼指令轉換為匯編語言指令及操作數。

x86機器指令格式包含一個可選的前綴字節、一個操作碼字段、一個可選的Mod R/M字節、若干可選的立即數字節,以及若干可選的內存偏移量字節。具備全部這些字段的指令很少。前綴字節覆蓋了目標處理器默認的操作數大小。操作碼字段是指令獨一無二的操作編碼。Mod R/M 字段指定了尋址模式和操作數。在使用寄存器操作數的指令中,Mod R/M 字節用一個3位標識符來表示每個寄存器操作數。

12.5 關鍵術語

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94738.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94738.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94738.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue3通過按鈕實現橫向滾動、鼠標滾動橫坐標滾動

效果圖&#xff1a;可點擊左右文字進行滾動、或通過滾動鼠標 內容左右滾動<template><div class"Home"><div style"display: flex;height: 100%;align-items: center;"><div click"scrollLeft()" style"width: 80px;t…

【Agent】AutoGen:LLM驅動的多Agent對話框架

文章目錄一、AutoGen簡介1.1 AutoGen的特點1.2 AutoGen的實現1.2.1 可對話Agent1.2.2 對話編程二、基于AutoGen構建多智能體系統2.1 構建步驟2.1 協作模式2.2 通信模型2.3 人機協同2.4 具體示例參考資料一、AutoGen簡介 AutoGen是微軟推出的一個Multi-Agent框架&#xff0c;允…

乙巳年閏六月十六凌晨感懷

乙巳年閏六月十六凌晨感懷 一段歷程一段情&#xff0c;兒郎崢嶸兒郎行。 歲月流金建功業&#xff0c;春秋風尚能潮贏。 路途苦樂人生度&#xff0c;評說成敗當下名。 百年孤寂留水墨&#xff0c;千載獨步守安寧。

Redis 分布式Session

一、引入依賴引入spring-session-data-redis依賴&#xff0c;不需要指定version&#xff0c;默認和springboot的version保持一致<!-- Spring Session Redis --> <dependency><groupId>org.springframework.session</groupId><artifactId>spring…

JAVA實現附件分片上傳

項目需求由于文件服務器的限制&#xff0c;單次調用文件上傳接口上傳的附件的大小不能超過500MB&#xff0c;對于超過500MB的附件需要分片上傳程序示例private Boolean uploadFile(File uploadFile, String uploadUrl, List<Object> fileList) {final long CHUNK_SIZE 5…

PyTorch環境安裝

pytorch安裝 建議&#xff08;非常強烈的那種&#xff09;用Anaconda創建一個虛擬環境&#xff0c;用于運行安裝你的PyTorch conda create -n universal python3.9 1. 基礎認知 cuDNN&#xff08;CUDA Deep Neural Network library&#xff09;是 NVIDIA 開發的用于深度學習…

機場風云:AI 云廠商的暗戰,廣告大戰一觸即發

文 | 大力財經機場廣告牌背后&#xff0c;一場決定云計算未來格局的隱形戰爭已悄然打響。當你匆匆走過首都機場T3航站樓的通道&#xff0c;巨幅屏幕上“阿里云&#xff1a;開源的力量”與不遠處“百度智能云&#xff1a;AI落地領導者”的廣告交相輝映。它們精準鎖定著日均10萬的…

MLE-STAR:谷歌AI推出的機器學習工程新范式,一種搜索驅動、精準優化的智能代理

最近看到 Google AI 發布了一個叫 MLE-STAR&#xff08;Machine Learning Engineering via Search and Targeted Refinement&#xff09;的新系統&#xff0c;說實話&#xff0c;第一眼看完論文和相關介紹后&#xff0c;我是有點震撼的。這不只是一次簡單的“LLM 自動化”拼湊…

3-防火墻

防火墻 一 防火墻概述防火墻概述防火墻是一個位于內部網絡與外部網絡之間的安全系統&#xff08;網絡中不同區域之間&#xff09;&#xff0c;是按照一定的安全策略建立起來的硬件或軟件系統&#xff0c;用于流量控制的系統&#xff08;隔離&#xff09;&#xff0c;保護內部網…

python opencv 調用 海康威視工業相機(又全又細又簡潔)

1.準備工作 準備一個海康相機 下載MVS 和SDK 海康機器人-機器視覺-下載中心 2.python MVS示例 &#xff08;說明&#xff1a;MVS里有很多python示例&#xff0c;可以直接運行&#xff0c;但沒有用opencv&#xff09; 下載完MVS后&#xff0c;我們打開路徑安裝路徑 我的&#…

計算機基礎·linux系統

Finalshell 用于遠程操控vmware中的linux系統 獲取虛擬機的IP地址 ifconfig命令&#xff0c;重啟系統后IP地址可能會變化&#xff01;問題&#xff1a;vmware子系統沒有網絡連接 winRservices.msc啟動這些服務問題&#xff1a;配置正確但是finalshell連接失敗 更新子系統中的ss…

8.結構健康監測選自動化:實時數據 + 智能分析,遠超人工

第一次接觸結構健康自動化監測系統&#xff0c;感覺成本很高&#xff0c;比人工好在哪里&#xff1f; 人工檢測是依靠目測檢查或借助于便攜式儀器測量得到的信息&#xff0c;但是隨著整個行業的發展&#xff0c;傳統的人工檢測方法已經不能滿足檢測需求&#xff0c;從人工檢測到…

【慕伏白】Android Studio 配置國內鏡像源

文章目錄配置HTTP代理修改 gradle 鏡像地址修改 maven 鏡像源重新同步配置HTTP代理 進入File --> Settings --> Appearance & Behavior --> System Settings --> HTTP Proxy 勾選 Auto-detect proxy settings --> Automatic proxy configuration URL &…

Spring Cloud系列—LoadBalance負載均衡

上篇文章&#xff1a; Spring Cloud系列—Eureka服務注冊/發現https://blog.csdn.net/sniper_fandc/article/details/149937589?fromshareblogdetail&sharetypeblogdetail&sharerId149937589&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link …

如何使用 pnpm創建Vue 3 項目

? 一、什么是 pnpm&#xff1f; pnpm 是一種更快、更高效的 Node 包管理工具&#xff0c;替代 npm 或 yarn&#xff0c;具有&#xff1a; 更快的安裝速度更節省磁盤空間&#xff08;包復用&#xff09;嚴格的依賴管理二、使用 pnpm 創建 Vue 項目的完整流程 ? 第一步&#xf…

Vite vs. vue-cli 創建 Vue 3 項目的區別與使用場景

Vite vs. vue-cli 創建 Vue 3 項目的區別與使用場景 Vite 和 vue-cli 都是 Vue 官方推薦的腳手架工具&#xff0c;但它們的架構、構建方式和適用場景有所不同。以下是它們的對比&#xff1a;1. 核心區別對比項Vite (推薦&#x1f525;)vue-cli (傳統)構建工具基于 ESM Rollup基…

VC6800智能相機:賦能智能制造,開啟AI視覺新紀元

在工業自動化與智能化浪潮奔涌的今天&#xff0c;精準、高效、智能的視覺檢測已成為提升生產力和品質的關鍵核心。VC6800智能相機應運而生&#xff0c;它不僅僅是一部相機&#xff0c;更是一個集強大視覺硬件與前沿AI算法于一身的 “工業智眼”&#xff0c;正深刻改變著各個領域…

(Python)Python爬蟲入門教程:從零開始學習網頁抓取(爬蟲教學)(Python教學)

一、爬蟲基礎概念 什么是爬蟲&#xff1f; 網絡爬蟲&#xff08;Web Crawler&#xff09;是一種自動獲取網頁內容的程序&#xff0c;它像蜘蛛一樣在互聯網上"爬行"&#xff0c;收集和提取數據。 爬蟲應用場景&#xff1a; 搜索引擎&#xff08;Google、百度&#…

dify前端源碼部署詳細教程

這兩天突發奇想&#xff0c;能不能dify源碼部署我只部署個前端&#xff0c;后端、數據庫什么的還是原來docker部署dify的本地部署和遇到的問題。按邏輯來說應該是行得通的&#xff0c;我就親自操作了下試下。 我這邊就以我以前使用docker部署好的1.3.1版本為例。docker安裝參考…

Web地圖服務規范,WMS服務是什么

Web地圖服務規范&#xff0c;WMS服務是什么&#xff1f; WMS&#xff0c;全稱 Web Map Service (網絡地圖服務)&#xff0c;是有OGC(開放地理空間信息聯盟)制定的一項標準化協議。他的核心功能是允許客戶端&#xff08;比如網頁瀏覽器或者GIS桌面軟件&#xff09;通過互聯網或者…