80386ASM程序設計基礎(四)

   算術運算指令,邏輯運算指令,移位指令
   AA.算術運算指令
   A.加減法運算ADD,ADC,INC,SUB,SBB,DEC,CMP,NEG
   a.ADD,和8086功能,用法相同,不過支持32位操作,下面的語句都是合法的。
   ADD  ESI,EDI
   ADD  EAX,DWORD  PTR  [1000H]
   b.ADC,帶進位的加法指令,即OPRDS+OPRDD+CF,其中OPRDS代表源操作數,OPRDD代表目的操作,CF代表進位標誌位,功能和用法與8086相同,支持32位操作。
   c.SUB,和8086相同,支持32位操作。
   d.SBB,帶進位的減法指令,即OPRDD-OPRDS-CF,其中OPRDS代表源操作數,OPRDD代表目的操作數,CF代表進位標誌位,功能和用法與8086相同,支持32位操作。
   e.DEC,減1操作,功能和用法與8086相同,支持32位操作。
   f.CMP,比較操作,功能和用法與8086相同,支持32位操作。
   g.NEG,求補操作,功能和用法與8086相同,支持32位操作。
   h.INC  加1操作,功能和用法與8086相同,支持32位操作。
  
   B.乘除法指令MUL,DIV,IMUL,IDIV
   a.MUL,無符號數乘法指令,和8086功能用法一樣,即指令中只給出一個操作,被乘數已默認,如果指令給出的操作數是32位的話,被乘數默認爲EAX,那麼乘積將存放在EDX:EAX中,其中EDX存放高32位,EAX存放低32位,如果此時EDX=0,即高32位爲0的話,那麼OF=0,CF=0,否則被置1。如果指令給出的操數作是16位的話,被乘數默認爲AX那麼乘積將放在DX:AX中,其中DX中將存放高16位,AX中存放低16位。如果指令給出的操作數是8位的話,被乘數默認爲AL,那麼乘積將放在AX,AH中存放高8位,AL中存放低8位。
  b.DIV,無符號數的除法指令,和8086一樣,指令給出一個操作數,被除數已默認。如果指令中給出的操作數爲32,那麼被除數將是EDX:EAX, 最終的商將存放在EAX, 餘數將存放在EDX中。如果指令給出操作數爲16位,那麼被除數爲EAX,最終得到的商放在AX,餘數放在EAX的高16位。如果指令中給出的操作數爲8位,那麼被除數是16位,最終得到的商將放在AL中,餘數放在AH中。
  c.IMUL,有符號數的乘法指令,除了具有8086的用法外,有新的形式:
    c1.IMUL DST,SRC;將源操作數SRC與目的操作DST相乘,並將結果送往DST。
    c2.IMUL DST,SRC1,SRC2;將源操作數SRC1與源操作數SRC2相乘,並將結果送往DST。
    使用這種形式必須遵守的規則,形式c1指令中目的操作數必須是16位或32位通寄存器,源操作數的長度必須與目的操作的長度一樣(8位立即數除外,即00H-FFH或80H-7FH),源操作數可以是通用寄存器,也可以是存儲單元或立即數。形式c2指令中的源操作數SRC1可以是通用寄存器也可以是存儲單元,源操作數SRC2必須是立即數,DST必須是16位或32位通用寄存器。呵呵,對於這些規則無需去問爲什麼,這是硬件的特性決定的,如果一定要問爲什麼,那隻能問INTEL公司的硬件工程師了:)。同時,有一點要注意的是:這兩種形式的指令,目的寄存器的長度與源操作數長度一樣(8位立即數除外),這樣的話,該指令事實上對有符號數和無符號數是一樣的,因爲乘積的低位部分均存儲在目的寄存器中,而高位部分在這兩種形式的指令中不予以存儲。
  d.IDIV,有符號數的除法指令,用法和8086相同,不過支持32位操作。  

  C.符號擴展指令CBW,CWD,CWDE,CDQ
  a.CBW,前面已介紹,在第三篇。
  b.CWD,前面已介紹,在第三篇。
  c.CWDE,是80386新增的指令。格式:CWDE。功能:將AX的符號位擴展到EAX的高16位中。
  d.CDQ,是80386新增的指令。格式:CDQ。功能,將EAX的符號位擴展到EDX中。
  e.以上四條指令均不影響標誌位。
  f.舉例說明:
  ;If AX=1234H,EAX=99991234H
  CBW;After processing the instruction,AX=1234,DX=0000H
  CDQ;After processing the instruction,EAX=99991234H,EDX=FFFFFFFFH

  BB.邏輯運算指令和移位指令NOT,AND,OR,XOR,TEST,SAL,SAR,SHL,SHR,ROL,ROR,RCL,RCR,SHLD,SHRD
  a.NOT,AND,OR,XOR,TEST這些指令的功能和用法與8086完全相同,不過它們支持32位操作。
  b.TEST,測試指令,該指令測試的結果並不回送到目的操作數和源操數。之所以要使用這條的指令,主要是因爲根據TEST指令得到的結果,進行程序的條件轉移。
  c.SAL,算術左移,功能和8086一樣,但在8086中,如果在移位的位數超過1位,那麼一定要移位的位數放在CX寄存器中。在80386中,可以不用這樣做,其它的移位指令也一樣。除了這一點以外,用法和8086一樣,當然也支持32位操作。以下的語句均是合法的。
  SHL AL,5;這在8086中是非法,但在80386中是合法的
  SHL WORD PTR [SI],3
  d.SAR,算術右移,將操作數右移指定的位數,但左邊的符號位保持不變,移出的最低位進入CF標誌位。
  e.SHL,邏輯左移,用法和功能與SAL一樣。
  f.SHR,邏輯右移,將操作右移指定的位數,同時每移一位,左邊用0補充,移出的最低位進入CF標誌位。
  g.說明:在80386中,實際移位的位數是指令中移位位數的低5位,也就是說移位位數的範圍在0-31或0-1FH,CF標誌位總是保留着目的操作數最後被移出位的值。當移位位數大於操作數的長度時,CF被置0。如果移位位數爲1,移位前後的結果的符號位都是一樣,那麼很明顯的是該操作數經移位後沒有移出,此時OF=0。這四條指令的移位示意圖(我畫的是16位操作數的移位示意圖,8位和32依此類推),SAL,SHL相當於乘法;SAR,SHR相當於除法。
  SAL:
  |-------------------------------------------------------------------------------------------|
  |CF|<-|bit15|bit14|bit13|bit12|bit11|bit10|bit9|bit8|bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|
  |-- ----------------------------------------------------------------------------------------|
  SHL:
  |-------------------------------------------------------------------------------------------|
  |CF|<-|bit15|bit14|bit13|bit12|bit11|bit10|bit9|bit8|bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|
  |--- ---------------------------------------------------------------------------------------|
  SAR:
    |--------------------------------------------------------------------------------------------|
  |-|bit15|bit14|bit13|bit12|bit11|bit10|bit9|bit8|bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|->|CF||
  | |---|----------------------------------------------------------------------------------------|
  |     ^
  |-----|最高位保持不變
  SHR:
     |--------------------------------------------------------------------------------------------|
  0->|bit15|bit14|bit13|bit12|bit11|bit10|bit9|bit8|bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|->|CF||
     |--------------------------------------------------------------------------------------------|
  h.ROL,循環左移,支持32位操作數,用法和8086一樣。
  i.ROR,循環右移,支持32位操作數,用法和8086一樣。
  j.RCL,帶進位的循環左移,支持32位操作數,用法和8086一樣。
  k.RCR,帶進位的循環右移,支持32位操作數,用法和8086一樣。
  l.ROL,ROR,RCL,RCR的移位示意圖(仍然以16位操作數來畫,8位/32位依次類推):
  ROL:
   |--------------------------------------------------------------------------------------------------|
   |<-|bit15|bit14|bit13|bit12|bit11|bit10|bit9|bit8|bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|<--------|
   |--------------------------------------------------------------------------------------------------|
   |--------------------------------------------------------------------------------------------------| 
  ROR:
   |-------------------------------------------------------------------------------------------|
   |->|bit15|bit14|bit13|bit12|bit11|bit10|bit9|bit8|bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|->|
   |-------------------------------------------------------------------------------------------|
   |-------------------------------------------------------------------------------------------|
 RCL:
   |-------------------------------------------------------------------------------------------------|
   |<-|CF|<-|bit15|bit14|bit13|bit12|bit11|bit10|bit9|bit8|bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|<-|
   |-------------------------------------------------------------------------------------------------|
   |-------------------------------------------------------------------------------------------------|  
  RCR:
   |-------------------------------------------------------------------------------------------------|
   |->|CF|<-|bit15|bit14|bit13|bit12|bit11|bit10|bit9|bit8|bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|->|
   |---- --------------------------------------------------------------------------------------------|
   |-------------------------------------------------------------------------------------------------|
  m.SHLD,80386新增的雙精度左位指令,指令格式:SHLD OPRD1,OPRD2,M
  n.SHRD,80386新增的雙精度右移指令,指令格式:SHRD,OPRD1,OPRD2,M
  o.m,n這兩條指令的使用規則是:源操作數OPRD1可以是16位或32位通用寄存器或者16位存儲單元或者32位存儲單元,源操作數OPRD2必須是16位或32位通寄存器,M表示移位次數,可以是CL寄存器,也可以是8位立即數。功能:SHLD是將源操作數OPRD1移M位,空出的位用OPRD2高端的M位來填補,源操作數OPRD2的內容不變,最後移出的位放在CF中;SHRD將源操作數OPRD1移M位,空出的位用OPRD2低端M位來填補,源操作數OPRD2保持不變,最後移出的位放在CF中,對於這兩條指令,當移位位數僅爲1的話,移出和移後的符號位不變的話,那麼OF=0,如果符號位不一樣的話,那OF=1。
  p.這兩條指令是80386新增的指令,舉兩個簡單的例子加以說明:
  p1.SHLD:
  MOV AX,8321H
  MOV DX,5678H
  SHLD AX,DX,1
  SHLD AX,DX,2
  分析一下該指令的詳細執行過程(用示意圖, 第一個圖畫的就是AX的內容):
  AX=8321h
  |-------------------------------|
  |1|0|0|0|0|0|1|1|0|0|1|0|0|0|0|1|  
  |-------------------------------|
  根據指令SHLD AX,DX,1,先左移一位,得到AX=0642H:
  |-------------------------------|
  |0|0|0|0|0|1|1|0|0|1|0|0|0|0|1|0|    CF=1   
  |-------------------------------|
  經過上一步的移位後,AX的最後一位(即bit0)空出來,其值爲0;根據指令的用法將用DX的第15位填充,填充後AX的內容爲:
  |-------------------------------|
  |0|0|0|0|0|1|1|0|0|1|0|0|0|0|1|0|   
  |-------------------------------|
  同時由於移位後AX的符號位與移位前AX的符號位不同,所以在移位過程中產生了溢出,OF=1,最後結果AX=0642H。
  同理,SHLD AX,DX,2,執行完這條指令後,最後結果爲AX=0644H
  p2.SHRD:
  MOV EAX,12345678H
  MOV EDX,99994599H
  SHRD AX,DX,1
  SHRD AX,DX,2
  分析一下該指令的詳細執行過程(用示意圖,第一個圖畫的是EAX的內容):
  EAX=12345678H
  |---------------------------------------------------------------|
  |0|0|0|1|0|0|1|0|0|0|1|1|0|1|0|0|0|1|0|1|0|1|1|0|0|1|1|1|1|0|0|0|
  |---------------------------------------------------------------|
  根據指令SHRD AX,DX,1,將AX右移一位得到EAX=091A2B3EH:
  |---------------------------------------------------------------|
  |0|0|0|0|1|0|0|1|0|0|0|1|1|0|1|0|0|0|1|0|1|0|1|1|0|0|1|1|1|1|1|0|
  |---------------------------------------------------------------|
  經過上一步的移位後,EAX的最高位(第31位)空出來用0填充,根據指令的用法,最EDX的第0位來填充,填充後EAX的內容爲:
  |---------------------------------------------------------------|
  |1|0|0|0|1|0|0|1|0|0|0|1|1|0|1|0|0|0|1|0|0|1|1|0|0|1|1|1|1|0|0|0|
  |---------------------------------------------------------------|
  即EAX=891A2B3EH,CF=0,OF=0
  同理,指令SHRD AX,DX,2,執行完這條件指令後,最後結果爲EAX=048D159C,CF=0,OF=0

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