跟着寫操作系統(彙編語言小錄)

    上次在經過一番折騰之後,總算是把寫操作系統的開發環境給搭建起來了,看了以下前面的程序,着實有些蛋疼的感覺阿,都是彙編,艾,普通2b學校,平時上課不上彙編,怎麼辦呢,只好去圖書館接了一本《彙編語言與接口技術》,一直以來,都有這麼一個想法,又想學得更多,又想學得更快,雖然知道這不是一個長久之計,怎麼說也可以應付暫時的需求亞,就這麼愉快的決定了。

    準備對照兩本書來研究算法,指令雖然找到了,但是發現後面的寄存器看都看不懂,算了,還是把彙編過一遍吧,這部,邊看書邊記錄,下面吧我這幾天來的總結列出來分享一下,同時也爲了方便以後查閱(順便說一下,這裏所有的指令都另加了英文註釋,個人認爲這樣的話比較容易記憶):

   (一)標誌位:
 


---------------------------------------------
| |NT|IOPL|OF|DF|IF|TF|SF|ZF| |AF| | |PF| |CF|
---------------------------------------------
        NT: nested task flag(286+) 嵌套任務標誌
        IF: interrupt enable flag 中斷使能標誌
        AF: auxilary carry flag 輔助進位標誌
        IOPL: I/O privilege level(286+) I/O特權級
        TF: trap flag 陷阱標誌
        PF: parity flag 奇偶標誌
        OF: overflow flag 溢出標誌
        SF: sign flag 註冊標誌
        CF: carry flag 僅爲標誌
        DF: direction flag 方向標誌
        ZF: zero flag 零標誌位
    (二)寄存器


1、通用寄存器
AX(accumulator)、BX(base)、CX(count)、DX(data)這些寄存器可以字(16位)或字節(8位)單位形式訪問;
SP(stack pointer)、BP(base pointer)、SI(source index)、DI(destination index),這些寄存器只能以字(16位)單位形式訪問。

2、專用寄存器
IP(instruction pointer)、SP(stack pointer);;
FLAGS又稱PSW(program status word)分爲:
①     條件碼
OF(overflow)、SF(sign)、ZF(zero)、CF(carry)、AF(auxiliary)、PF(parity)
②     控制標誌
DF(direction)
③     系統標誌位
TF(trap)、IF(interrupt)、IOPL(I/O privilege level)

3、段寄存器
CS(code)、DS(data)、SS(stack)、ES(extra)

    (三)彙編指令

一、數據傳送指令
1.通用數據傳送指令.
MOV----> move:
    1.由立即數或寄存器位數決定傳遞的位數;
    2.目的操作數和源操作數不能都是存儲器操作數;
    3.不能用CS,IP作爲目的操作數,即兩個寄存器內容不能隨意改變;
    4.不允許在段寄存器間傳輸數據(MOV DS,ES是錯誤的);
    5.不允許用立即數作爲目的操作數;
    6.不能向段寄存器傳送立即數,可通過CPU的通用寄存器AX完成.
MOVSX---->extended move with sign data
MOVZX---->extended move with zero data
PUSH---->push (POP---->pop)
        壓入(送出)存儲器操作數,寄存器操作數或立即數(16位寄存器或存儲器)
    注意:
        1.只允許按字訪問堆棧,即兩類指令操作數必須爲16位寄存器或存儲單元操作數
        2.CS不能作爲目的操作數
PUSHA---->push all
POPA---->pop all
PUSHAD---->push all data
POPAD---->pop all data
BSWAP---->byte swap
XCHG---->exchange
        可實現通用寄存器及通用寄存器和存儲器之間數據交換
CMPXCHG---->compare and change
XADD---->exchange and add
XLAT---->translate
    格式:
        XLAT label
        XLAT ;AL<-DS:((BX) + (AL))
    功能:轉換表中一個字節代換AL寄存器中的內容可用於碼轉換
2.輸入輸出端口傳送指令.
IN---->input 累加器, 端口
    把一個字節/字由輸入端口傳送到AL/AX
OUT---->output 端口, 累加器


3.目的地址傳送指令.
LEA r16, mem---->load effective address
    要求:r16爲一個16位通用寄存器, mem爲存儲單元
    功能:將有效地址(地址偏移量)送至通用寄存器,而非將存儲單元內容送至通用寄存器
    注意:
        1.兩個操作數不能同時爲存儲器操作數
        2.任一個操作數都不能使用段寄存器,也不能使用立即數
    LEA BX, VARWORD 等效 MOV BX, OFFSET VARWORD
    區別在於後者用僞指令OFFSET,由編譯器在編譯時賦值,而前者在執行時賦值


LDS---->load DS (LES---->load ES)
    將內存中連續4個字節內容高16位送到DS(ES)以及低16位送至指定的通用寄存器
    注意:dest必須爲通用寄存器之一,src必須爲內存操作數
    例:
        1.LDS DI, [2130] ;將2130h和2131h單元內容送DI,2132H和2133h單元送DS
        2.EXDWORD DD 12345678H
          LDS SI, EXDWORD ;將1234H送DS, 5678h送SI
LFS---->load FS
LGS---->load GS
LSS---->load SS
4.標誌傳送指令.
LAHF---->load AH from flag
        取標誌指令,將標誌寄存器低8位送AH
SAHF---->save AH to flag
        存標誌指令,將AH內容送至標誌寄存器低8位
PUSHF---->push flag
POPF---->pop flag
PUSHD---->push dflag
POPD---->pop dflag


二、算術運算指令
        20條算術運算指令,除加減1外都是雙操作數指令,雙操作數必須有一個在寄存器中,雙操作數目的操作數以及單操作數不允許使用立即數


ADD---->add
        1.不允許兩個存儲器單元內容相加;
        2.不允許兩個段寄存器之間相加;
        3.對標誌位有影響,主要是CF,ZF,OF,SF


ADC---->add with carry
        在完成兩個字或字節相加的同時,還要考慮CF的值來判斷是否加1
        源操作數和目的操作數不能同時爲存儲單元,段寄存器不能進行算數運算


INC reg/mem ---->increase 1
        要求:reg是8或16位的通用寄存器,mem爲8或16位的存儲單元(不能爲立即數)
        源操作數加1再送回,一般用於循環程序指針修改,只有一個操作數;
        影響AF,OF,PF,SF和ZF,不影響CF,將操作數視爲無符號數


SUB---->substract
        要求同ADD指令


SBB---->substract with borrow
        要求同ADC
DEC---->decrease 1
        要求同INC


NEG---->negative
        將操作數取補後送回源操作數
        操作數可以爲8或16位通用寄存器或存儲器操作數,不能爲立即數
        注意:只有操作數爲0才使CF=0,否則CF=1,若操作數值爲-128(80H)或-32768(8000H),執行取補指令結果沒有變化,但此時溢出標誌OF=1


CMP dest, src ---->compare
        dest - src不送回結果,根據結果置標誌位


組合的BCD調整指令:
        DAA---->decimal add with adjust
                對在AL中的和(由兩個組合BCD碼相加)進行調整產生一個組合的BCD碼
                若AL中的低四位在A-F之間,或AF=1,則AL<-(AL)+6,且AF位置1
                --------高四位-------------CF=1----AL<-(AL)+60H--CF----1
        DAS---->decimal adjust on substract
                對在AL中的差(由兩個組合BCD碼相減)進行調整產生一個組合的BCD碼
                若AL中的低四位在A-F之間,或AF=1,則AL<-(AL)-6,且AF位置1
                --------高四位-------------CF=1----AL<-(AL)-60H--CF----1
        影響標誌AF,CF,PF,SF和ZF,不影響OF


未組合的BCD調整指令:
        AAA---->ascII add with adjust
                對ADD指令運算後AL內容進行調整
        AAS---->ascII adjust on substract
                --SUB------------------------
        AAM---->ascII adjust on multiplication
                --MUL----------AX中乘積進行BCD調整
        AAD---->ascII adjust on divide
                調整DIV前AH,AL中除數,以便除法得到商爲有效未組合BCD數
        AAA,AAS會影響AF,CF,對OF,PF,SF和ZF沒有意義,需要緊跟調整命令後
MUL---->multiplication
        不帶符號8或16位二進制乘法
        格式 MUL REG/MEM ----> 隱含的AL/AX乘REG/MEM
                 MUL DEST, SRC
        DEST可爲8或16位通用寄存器或存儲器,src可爲8或16位通用寄存器,存儲單元或立即數,但dest,src不能同時爲存儲器


IMUL---->integer multiplication
        要求同MUL,帶符號乘法


DIV---->divide
        要求同mul
        無符號字或字節相除時,所得商及餘數均爲無符號數,分別放在AL和AH中,無符號雙字或字相除,所得商餘數也位無符號,放在AX和DX中


IDIV---->integer divide
        要求同div,帶符號除法


CBW---->change byte to word
        將AL中單字節數的符號擴展到AH中;若AX<80H,則0->AH;若AL>=80H,則FFH->AH
CWD---->change word to double word
        將AX中單字節數的符號擴展到DX中;若AX<8000H,則0->DX;若AL>=8000H,則FFFFH->DX
CWDE---->change word to double word with sign to EAX
CDQ---->change double word to quadrate word
三、邏輯運算指令
AND---->and
OR---->or
XOR---->xor   Exclusive OR
        以上三個src和dest不能同時爲存儲單元,段寄存器不能進行邏輯運算


NOT---->not
TEST---->test 按位與,只存標誌,不存結果


SAL reg/mem,1/CL ---->arithmatic shift left 算術左移1次或CL指定的次數
SAR reg/mem,1/CL ---->arithmatic shift right --右-------------------
SHL ------------ ----->shift left                       邏輯左移----------------
SHR ------------ --->shift right                        ----右------------------
ROL ------------ --->rotate left                        循環左移----------------
ROR ------------ --->rotate right                       ----右------------------
RCL ------------ ---->rotate left with carry 帶進位 ROL
RCR ------------ ---->rotate right with carry 帶進位 ROR
四、串指令
MOVS---->move string
CMPS---->compare string
SCAS---->scan string
LODS---->load string
STOS---->store string
        以上指令後加B表字節,加W表字
REP---->repeat (CX<-CX-1,=0爲止)
REPE---->repeat when equal CX或ZF=0停止執行
REPZ---->repeat when zero flag 同上
REPNE---->repeat when not equal  CX或ZF=0停止執行
REPNZ---->repeat when zero flag 同上
        以上指令不能單獨使用,只能加在串操作指令前來控制跟在其後的字符串操作指令,使之重複執行,重複前綴不影響標誌位
REPC---->repeat when carry flag
REPNC---->repeat when not carry flag


五、程序轉移指令
1>無條件轉移指令(長轉移)
JMP---->jump
CALL---->call
        CALL DST:段內直接調用,DST爲子程序名
        CALL SRC:段內間接調用,SRC爲16位寄存器或各種尋址方式的存儲器操作數
        CALL DST:段間直接調用,DST給出子程序入口地址完整信息(段基址CS偏移量IP)
        CALL SRC:段間間接調用,SRC爲各種尋址方式的存儲器操作數
RET---->return
        段內返回:把抱回堆棧斷點偏移送入指令指針寄存器IP,返回調用程序處繼續執行
        段間返回:段地址送至CS寄存器-----------------IP,----------
        RET n:最後SP<-SP+n
RETF---->return far
2>條件轉移指令(短轉移,-128到+127的距離內)
-------------無符號數條件轉移--------------------------
JA/JNBE---->jump when above/jump when below or equal
JAE/JNB---->jump when above or equal/jump when not below
JB/JNAE---->jump when below/jump when not above or equal
JBE/JNA---->jump when below or equal/jump when not above
JC---->jump when has carry flag
JNC---->jump when not has carry flag
JE/JZ---->jump when equal/jump when has zero flag
JNE/JNZ---->jump when not equal/jump when not has zero flag
JNP/JPO---->jump when not has parity/flag/jump when parity flag is odd
JP/JPE---->jump when has parity flag/jump when parity flag is even


-------------帶符號數條件轉移--------------------------
JG/JNLE---->jump when greater/jump when not less or equal
JGE/JNL---->jump when greater or equal/jump when not less
JL/JNGE---->jump when less/jump when not greater or equal
JLE/JNG---->jump when less or equal/jump when not greater
JNO---->jump when not has overflow flag
JNS---->jump when not has sign flag
JO---->jump when has overflow flag
JS---->jump when has sign flag


--------------根據ECX中值決定轉移指令格式及功能--------
JCXZ---->jump when CX is zero
JECXZ---->jump when ECX is zero
3>循環控制指令(短轉移)
LOOP---->loop
        現將CX減1,判斷爲0則退出循環
LOOPE---->loop equal LOOPZ---->loop zero
        執行時,將CX寄存器內容減1會送CX寄存器,ZF不受CX減1影響
        if(CX!=0 && ZF==1){
                轉移到目的標號執行,IP<-IP + 偏移量
        }else if (CX!=0 && ZF==0){
                停止循環,按指令順序執行
        }else {
                停止循環,按指令順序執行
        }
LOOPNE---->loop not equal LOOPNZ---->loop not zero
        執行時,將CX寄存器內容減1會送CX寄存器,ZF不受CX減1影響
        if(CX!=0 && ZF==0){
                轉移到目的標號執行,IP<-IP + 偏移量
        }else if (CX!=0 && ZF==1){
                停止循環,按指令順序執行
        }else {
                停止循環,按指令順序執行
        }
4>中斷指令
INT n ---->interrupt
        n爲中斷類型碼(0-255),n確定即可到0000H段中偏移地址4*n開始4個單元找到該程序入口地址
        1.標誌寄存器壓入堆棧保存,SP<-SP-2,SS:[SP]<-標誌寄存器內容
        2.禁止新的可屏蔽終端和單步中斷,IF<-0,TF<-0
        3.斷點地址壓入堆棧保存,SP<-SP-2,SS:(SP)<-CS,SP<-SP-2,SS:(SP)<-IP
        4.取中斷服務程序起始地址,CS<-0000H:[4n+3]和0000H:[4n+2]內容,IP<-0000H:[4n+1]和0000H:[4n]的內容


INTO---->overflow interrupt
        若OF=1啓動中斷子程序(INT N,其中N=4),OF=0則無操作
        1.標誌寄存器壓入堆棧保存,SP<-SP-2,SS:[SP]<-標誌寄存器內容
        2.禁止新的可屏蔽終端和單步中斷,IF<-0,TF<-0
        3.斷點地址壓入堆棧保存,SP<-SP-2,SS:(SP)<-CS,SP<-SP-2,SS:(SP)<-IP
        4.取中斷服務程序起始地址,CS<-0000H:[0012H],IP<-0000H:[000AH]


IRET---->interrupt return
        執行中斷返回指令時,自動完成斷點出戰(CS出戰,IP出戰)和flags出棧
        1.斷點地址出棧恢復,IP<-SS:(SP),SP<-SP+2,CS<-SS:(SP),SP<-SP+2
        2.標誌寄存器出棧恢復,標誌寄存器<-SS:(SP),SP<-SP+2
5>處理器控制指令
HLT---->halt
        使處理器暫時停止執行後繼指令,直到不可屏蔽中斷NMI發生,可屏蔽中斷INTR被識別或處理器復位爲止


WAIT---->wait
        等待8086信號線上!TEST有效信號,=1表CPU處於等待狀態,並繼續執行WAIT指令,每隔5個時鐘週期測試一次,一旦!TEST=0結束


ESC---->escape
        使某個協處理器以從CPU取得的操作數進行處理
LOCK---->lock
        總線鎖定前綴,在執行帶有LOCK前綴的命令後,禁止其他處理器佔用總線
NOP---->no operation
        執行空操作,只會引起IP的變化,用於填充內存形成正確轉移地址和延時作用


STC---->set carry CF<-1
CLC---->clear carry CF<-0
CMC---->carry make change CF取反
STD---->set direction DF<-1
CLD---->clear direction DF<-0
STI---->set interrupt IF<-1
CLI---->clear interrupt IF<-0
六、僞指令
DW---->definw word
PROC---->procedure
ENDP---->end of procedure
SEGMENT---->segment
ASSUME---->assume
ENDS---->end segment
END---->end




  Move)
  MOVC (Move Code)
  MOVX (Move External)
  XCH     (Exchange)
  PUSH
  POP
  AJMP   (Absolute Jump)
  LJMP    (Long Jump)
  SJMP    (Short Jump)
  JMP      (Jump Indirect)
  JZ         (Jump Zero)
  JNZ      (Jump Not Zero)
  JC         (Jump if Carry)
  JNC      (Jump if Not Carry)
  JB         (Jump if Bit is set)
  JNB      (Jump if Not Bit)
  JBC       (If Bit is set and Clear Bit)
  CJNE    (Compare and Jump if Not Equal)
  DJNZ    (Decrement and Jump if Not Zero)
  ACALL (Absolute Call)
  LCALL  (Long Call)
  RET       (Return)
  NOP      (No Operation)
  ADD
  ADDC  (Add with Carry)
  SUBB   (Substract with Borrow)
  MUL     (Multiply)
  DIV       (Divide)
  INC      (Increment)
  DEC     (Decrement)
  ANL     (Logical AND)
  ORL     (Logical OR)
  XRL     (Logical Exclusive OR)
  CPL     (Complement)
  CLR     (Clear)
  SEBT   (Set Bit)
  RL        (Rotate Left)
  RR        (Rotate Right)
  RLC     (Rotate Left throught the Carry flag)
  RRC     (Rotate Right throught the Carry flag)
  XCHD
  SWAP
  DA       (Decimal Adjust)


  ORG    (Origin)
  DB       (Define Byte)
  DW      (Define Word)
  EQU     (Equal)
  DATA
  XDATA (External Data)
  BIT
  END

    中英文對照基本來自這篇文章,當然中文註釋部分是從前文提到的那本彙編書上找到依次找到,記錄一下,以供查閱。

    恩,ok,指令大致看過一遍了,接下來把看一下後面一個章節的彙編語言程序設計,就回歸我的操作系統的實現。perfect!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章