【匯編語言】理解8086CPU中,不同類型的寄存器和匯編指令規則的聯系(會繼續更新)

0 前言

你是否因為匯編指令繁雜的規則而苦惱呢?作者本人也很煩,因為往往教材中只告訴我們規則,卻不告訴我們為什么,沒有原因就直接記憶,負擔太大,后期靈活運用也增添阻力,因此,我經過自己的思考去為你解釋為什么有些規則是內樣的,本文并不是深入硬件原理,只在匯編語言層級,從邏輯上說明原因。

x86指令集的核心原則:操作數最多只能有一個是內存單元,另外的可以是立即數或者寄存器

1 寄存器的分類

我先從其他博客為你找來了8086CPU的全部寄存器及其功能
原文鏈接在此

通用寄存器:
ax——accumulate register——累加器
bx——based register——基地址寄存器
cx——count register——計數器
dx——data registered——數據寄存器

段寄存器:
cs——code segment——代碼段
ds——data segment——數據段
ss——stack segment——棧段寄存器
es——extra segment——附加段寄存器

特殊功能寄存器:
ip——instructor point——指令指針寄存器
sp——stack point——堆棧指針寄存器
bp——base point——基礎指針
si——source index——源變址寄存器
di——destination index——目的變址寄存器
psw——program state word——程序狀態字

Psw的常用標志:
OF(11位-overflow flag-溢出標志位)——OV(overflow-溢出)——NV(not overflow-沒溢出)
DF(10位-direction flag-方向標志位)——DN(down-下方)——UP(up-上方)
IF(9位-interrupt flag-中斷標志位)——EI(enable interrupt-允許中斷)——DI(disabled interrupt-不允許中斷)
TF(8位-trap flag-陷阱標志位)
SF(7位-sign flag-負號標志位)——NG(negative-負)——PL(plus-正)
ZF(6位-zero flag-零值標志位)——ZR(zero-為零)——NZ(not zero-不為0)
AF(4位-auxiliary carray flag-輔助進位標志位)——AC(auxiliary carry-有輔助進位)NA(not auxiliary carry-沒有輔助進位)
PF(2位-parity flag-奇偶標志位)——PE(parity even-偶)——PO(parity odd-奇)
CF(0位-carry flag-進位標志位)——CY(carried-有進位)——NC(not carried-沒進位)

不過我想說的是,這些內容看看就好,平時做對應內容學習的時候,作為參考資料就可以。

我根據匯編指令的規則,將其重新進行了分類。

1.1 煩人的匯編指令規則

我們知道,通用寄存器,用于存放一般的數據。

那么:

  • 一般的數據到底是什么?
  • 通用寄存器到底用來存什么數據的?
  • 它能夠存放來自哪些地方的數據?
  • 它存放的數據又能夠流向那些地方?

不知道你有沒有想過這些問題,不知道你有沒有因為8086CPU基本指令的一些規則而煩惱,例如

  • mov 段寄存器,通用寄存器允許:mov ds,ax允許,但是mov cs,ax又不允許了
  • mov 段寄存器,通用寄存器允許,但是add 段寄存器,寄存器又不允許了
  • mov 通用寄存器,立即數允許,但是mov 段寄存器,立即數又不允許了
  • IP不能作為操作數,而jmp指令又可以修改CS:IP的值
  • ……

不知道你煩不煩,反正我是煩了,這與高級語言不同,因為他們都是寄存器啊,憑什么有的行,有的就不行了

但是仔細想想,高級語言,其實是將不同操作的內容,明確分類了!,并且將一些容易出錯的操作,直接封裝了。

順著這個思路,我們是不是也可以將寄存器,按照其指令規則進行分類呢?我們可以做出嘗試!

其實這些規則,主要是因為硬件不允許,沒有建立數據通路,又或者是因為邏輯不合理而禁止某些規則。

邏輯不允許我們還能理解,但是硬件數據通路的建立,這個傷腦筋了,我們力求,通過邏輯理解規則,從而掌握規則

1.2 通用寄存器

什么叫通用!!就是它能夠干好多事情,它受到的制約比較小!

有些其他寄存器不能直接與內存交流的,它可以來幫忙傳信

它自己也有功能的劃分,但是不是很明顯,但是我仍然建議你編輯匯編語言的時候,按照其功能使用,除非不夠用,其他的也可以來幫忙。

  • AX:累加寄存器,可以用了存儲由運算器得到的數據
  • BX:基地址寄存器,可以用來存放基地址
  • CX:計數器,載入程序的時候存放機器碼的大小,它也可以干別的事
  • DX:數據寄存器,用來存放數據

他們的區別不明顯,允許相互混用,通常,通用寄存器,存儲的是數據,可以代表數值或者符號

  • 數值:1,2,3……
  • 符號:中文,韓文……

1.3 段寄存器

段寄存器,就是用來存放段地址的,因此不能隨意改變,根據不同的功能,權限也不一樣。

這里補充一個概念

數據
數值型數據,如:1,2,3
非數值型數據,如:中文

1.3.1 段寄存器數據的含義

段寄存器中的數據含義
它是數據,它代表的是某個段的段地址,它并不是代表某一個數值或者符號,因此它不能與通用寄存器進行數值運算

因此你就理解,為什么add sub指令的操作數不能是段寄存器。

而對于mov指令,并不是全部的段寄存器都不能作為操作數,因為mov做的是數據傳送工作,并不是運算工作,因此部分操作允許數據傳送到段寄存器中,以完成某個段的段地址的指定

我們接下來以CSDS為例,帶你理解一些指令的規則,更加細節的規則,可以根據本文的思路自行完成。

1.3.2 CS(code segment 代碼段寄存器)

CS是非常重要的,程序的指令執行依靠CS:IP指向的位置,因此CS和IP不能隨意更改。

  1. IP不能作為任何指令的操作數,它通常是CPU自動修改的,jmp指令是專門修改CS:IP的指令,以實現指令的跳轉jmp指令的用法請自行查閱資料
  2. CS的要求相對放寬一點,在mov指令中,它可以作為源操作數,也就是可以把它的數據傳出去,但是,不能作為目標操作數,除了專用的jmp等一類轉移指令(先不用管,知道他們可以修改CS和IP就可以了),別的指令不能修改CS和IP的值

下面的指令是不允許的

mov cs,ax

下面的指令是允許的

mov ax,cs

想要修改CS:IP需要以下指令

jmp 2000H:0

jmp,全稱jump,有跳轉的意思,也就是指令的跳轉,執行之后:CS = 2000H,IP = 0

總結一下

  1. cs不能做運算,add sub運算等指令中,所有段寄存器都不能作為操作數
  2. cs可以mov到其他寄存器mov ax,cs,也可以mov到內存單元mov [0],cs,此時,把CS中的內容,當成一般數據,傳到別的地方。
  3. jmp等轉移指令,可以修改CS:IP的值,實現指令的跳轉

1.3.3 DS(date segment 數據段寄存器)

DS用來存儲數據段的段地址

我們知道,在內存單元中找到數據,需要DS:EA指向它,因此,涉及到存儲器尋址的指令,都需要修改DS的值,并且將EA(有效地址,又叫偏移地址)告訴指令。

下面用debug模式中的指令舉例(而不是以標號代替地址的匯編源程序指令)

; 修改DS的值
mov ax,1000H
mov ds,ax
; 指定EA
mov bx,[0]

以上程序,DS:EA = 1000:0,bx將會被賦予這個地址指向的內存單元的字型數據

對于DS,你應該已經很清楚它的功能的,它是幫助CPU,在存儲器中找到數據段內的數據的

既然它是擅長找東西的,那么修改它的數據也就自然合理,以下mov指令都是允許的

  1. mov ds,通用寄存器
  2. mov ds,內存單元
  3. mov 內存單元,ds (ds當作一般性數據)

舉例如下

mov ds,ax
mov ds,[0]
mov [0],ds

這里,ax可以是其他的通用寄存器,[0]可以是存儲器尋址方式中的其他類型

重點強調,如果想要用立即數修改DS,指令mov ds,1234H不允許的,這與8086CPU的硬件實現有關,你可以理解為,沒有相關數據通路能夠立即數直接進入DS中

需要使用兩條指令來完成mov ds,1234H想要做的事情

mov ax,1234H
mov ds,ax

這兩條指令會非常常見,就相當于是:直走走不通,只能繞路而行


其他的內容,以后會逐步更新


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

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

相關文章

System V IPC之信號燈

信號燈也叫信號量 用于進程/線程同步或互斥的機制 信號燈的類型 1.Posix 無名信號燈 2.Posix 有名信號燈 3.System V 信號燈 信號燈的含義 計數信號燈(1和2都是) System V信號燈是一個或多個計數信號燈的集合(可操作集合中的多個信號燈&…

【VS 2017 C語言 匯編語言】如何使用VS 2017,通過反匯編查看C語言代碼對應的32位x86匯編語言 VS 2017單步調試的使用

0 前言 本文適用于VS的大多數版本&#xff0c;本文以VS 2017為例進行講解。 1 編輯C語言代碼 首先&#xff0c;在VS編譯器中&#xff0c;創建項目&#xff0c;敲一段C語言代碼&#xff0c;這個過程不解釋了&#xff0c;如果不會請百度。 #include <stdio.h> #include…

System V IPC之共享內存

共享內存是一種最為高效的進程間通信方式&#xff0c;進程可以直接讀寫內存&#xff0c; 而不需要任何數據的拷貝 共享內存在內核空間創建&#xff0c; 可以被進程映射到用戶空間訪問 由于多個進程可同時訪問共享內存 &#xff0c; 因此需要同步和互斥機制配合使用 共享內存的使…

【匯編語言】結合C語言,使用VS 2017調試模式下的反匯編工具學習32位x86匯編指令

0 前言 簡要說明x86系列指令集的整體概況與變化。 我給到你補充學習內容&#xff1a;使用VS學習匯編語言的教程 1 8086CPU到現代CPU的變化 做一些了解即可&#xff0c;不是絕對的&#xff0c;取決于設計工藝以及用途&#xff0c;不同計算機不一樣也正常。 1.1 CPU位數與地…

System V IPC之消息隊列

消息隊列由消息隊列id來唯一標識 消息隊列就是一個消息的列表 用戶可以在消息隊列中添加消息 讀取消息 消息隊列可以按照類型來發送和接收消息 消息隊列使用步驟 打開/創建消息隊列 msgget 向消息隊列發送消息 msgsnd 從消息隊列接收消息 msgrcv 控制消息隊列 msgctl 創建/打開…

【匯編語言】學習源頭知識:XLAT指令的本質(待更新)

0 前言 帶你理解XLAT指令的本質. 我想讓你清楚的是&#xff0c;XLAT指令 本質就是數據的傳送&#xff1a;本質就是完成mov指令的傳送功能&#xff0c;只不過源操作數的尋址方式是[bxal]&#xff0c;目標操作數是al表象是數據的轉換&#xff1a;例如將十六進制轉換為ASCII字符…

進程間通信————信號

信號 信號是在軟件層次上對中斷機制的一直模擬&#xff0c;是一種異步通信方式 linux內核通過信號通知用戶進程&#xff0c; 不同的信號類型代表不同的事件 進程對信號有不同的響應方式 缺省方式 忽略信號 捕捉信號 SIGKILL和SIGSTOP這兩個信號量 級別很高 只能執行默認操作…

【匯編語言】清華大學學堂在線《匯編語言程序設計》課程學習筆記

0 前言 全是基于x86系列處理器 1 寄存器與存儲器的區別 2 匯編程序員眼中的系統結構 指令寄存器 PC&#xff08;Program Counter&#xff09; 指向下一條指令的地址 16位 CS:IP32位 EIP64位 RIP 寄存器與寄存器堆&#xff08;Registers&#xff09; 在處理器內部以名字方…

進程間通信————無名管道

無名管道 只能用于具有親緣關系的進程之間的通信 單工的通信模式 具有固定的讀端和寫端 無名管道創建時會返回兩個文件描述符 分別用于讀寫管道 只能用于親屬關系之間 創建無名管道 #include <unistd.h> int pipe(int pfd[2]) 成功返回0 失敗返回EOF pfd包含兩個元素的…

什么是計算機思維?2個簡單表達式讓你理解!

0 前言 本文以十進制整數為例&#xff0c;使用2個最簡單的表達式char a -20;和char c a b;,為你深入淺出地講解計算機思維&#xff0c;力求將抽象的計算機思維具象化講解&#xff0c;同時&#xff0c;我將為你描述一個宏大的計算機世界的藍圖。 計算機思維與核心思想概要&a…

進程間通信————有名管道

有名管道 特點&#xff1a; 對應管道文件 可用于任意進程之間進行通信 打開管道時 可指定讀寫方式 通過文件I/O操作 內容存放在內存中 當讀端和寫端都不存在 管道內容自動釋放 當讀端和寫端只存在一個 將會無法打開管道文件 管道文件大小永遠為0 因為管道中的內容保存在內…

【匯編語言】8086匯編的loop循環與[bx]尋址(王爽第五章5.5節學習筆記)

計算FFFF:0 ~ FFFF:B單元中數據的和&#xff0c;結果存儲到dx中 1 分析與解決 內存單元&#xff1a;字節型數據目標寄存器&#xff1a;dx&#xff0c;字型寄存器&#xff0c;不匹配數據范圍&#xff1a;dx不會超&#xff0c;但是dl會超&#xff0c;因此必須用dx將字節型數據&a…

Linux下數據庫(sqlite3)學習筆記

sqlite3 數據庫安裝 1. 本地安裝 sudo dpkg -i *.deb 2.在線安裝 sudo apt-get install sqlite3 3.使用壓縮包解壓 壓縮包下載路徑&#xff1a;鏈接&#xff1a;https://pan.baidu.com/s/1xHLZGObQODUGBReNEi3KKQ 提取碼&#xff1a;zjqv SQLITE3 基本命令 兩種命令 1.以…

【匯編語言】8086、x86-32和C語言【賦值語句 和 數組】的對比學習(王爽學習筆記:5.8段前綴的使用)

0 前言 這里給出兩種思路&#xff0c;都比王爽老師書上的做法要簡單高效&#xff0c;事實上&#xff0c;理解指令的本質&#xff0c;就能達到靈活應用&#xff0c;這樣才能打破規則 題目&#xff1a;將內存ffff:0 - ffff:b的數據&#xff0c;復制到內存ffff:10 - ffff:1b中 備…

signal------SIGCHLD

因為筆者之前的文章里面有錯誤&#xff0c;今天發現&#xff0c;立馬做個修改。在下面我的一段關于sigchld信號相對于直接調用wait函數的好處時&#xff0c;我說調用wait函數要一直檢測子進程是否執行完其實是錯誤的&#xff0c; wait是阻塞函數&#xff0c;當主進程調用wait函…

為什么要學習匯編語言?如何正確學習匯編語言?

匯編語言是計算機系統結構的接口&#xff0c;它介于軟硬件之間&#xff0c;學習的時候&#xff0c;必須結合軟件和硬件來學習。 1 向上結合高級語言 學習匯編語言的時候&#xff0c;不可孤立學習匯編語言&#xff0c;當今時代很少之間用到匯編語言編程&#xff0c;但是使用匯…

數據庫Sqlite3

sqlite3 數據庫安裝 1. 本地安裝 sudo dpkg -i *.deb 2.在線安裝 sudo apt-get install sqlite3 SQLITE3 基本命令 兩種命令 1.以 . 開頭的稱之為系統命令 .help 幫助 .quit 退出 .exit 退出 .databases 查看打開的數據庫&#xff08;顯示數據庫的名字和路徑&#xff…

【匯編語言】(王爽)實驗4解答

題目1 編程&#xff1a;向內存0:200 - 0:23F 中存放數據 0 - 3FH ; 向內存 0:200 ~ 0:23f 寫入數據0~3fH【字節型數據】 assume cs:code code segmentstart:mov ax,0mov ds,axmov bx,0200H ; 偏移地址mov al,0 ; 數據mov cx,03fH1H ; 0 ~ 3FH 共 (3F 1)Hs:mov [bx],alinc b…

軟考安全工程師歷年真題匯總

2019年上半年信息安全工程師考試真題與答案&#xff08;下午題&#xff09; https://blog.csdn.net/jayjaydream/article/details/90683127 2018年上半年信息安全工程師考試真題與答案&#xff08;上午題&#xff09; https://www.moondream.cn/?p681 2018年上半年信息安全工…

【匯編語言】8086匯編,快速搞定各種尋址方式:立即數尋址 / 寄存器尋址 / 存儲器尋址

0 前言 眾所周知&#xff0c;對于8086匯編語言&#xff0c;有幾大尋址方式&#xff0c;不過我覺得這個好墨跡&#xff0c;會用就可以了&#xff0c;為什么命名這么多&#xff0c;這次只說本質&#xff0c;不說命名&#xff0c;至于命名&#xff0c;還是得知道&#xff0c;畢竟…