1. 程式人生 > >AT&T 彙編四則運算

AT&T 彙編四則運算

1 :加法

   1.1  add   source ,destination

    ADD指令可以將8,16,32位指令相加。其中b(用於位元組),w(用於字),或者l(用於漢字)

    使用add指令特別關注溢位問題,addb超過255就會溢位,標誌位設定為1,addw 超過65525就會溢位,設定標誌位為1.有時     候程式設計師不清楚何時溢位,此時溢位標誌就很重要了 .

.section .data  
output:
      .asciz " THe result id %d\n"
.section .text
.globl _start
_start:
      movl $-1590876934 ,%ebx
      movl $-1259230143, %eax
      addl %eax,%ebx
      jo over 
      pushl %ebx
      call printf
      add $8,%esp
      pushl $0
      call exit
over:
      pushl $0
      pushl $output
      call printf
      add $8 ,%esp
      call exit

       

jo 是判讀指令,溢位後程序跳轉到over,因此如果溢位,則輸出為0

1.2  adc   source ,destination

          處理特別大的資料時,一個32位的暫存器不能存放,則分開至2個或者多個32位暫存器,具體看例程:

.section .data  
data1:
  .quad 7252051615 #顯示64位帶符號的數值
data2:
  .quad 5732348928
output:
      .asciz " THe result is %d\n"
.section .text
.globl _start
_start:
      movl data1,%ebx  #低32位
      movl data1+4 ,%eax   #高32位
      movl data2,%edx
      movl data2+4 ,%ebx
      addl  %ebx,%edx    #低位暫存器加法
      adcl  %eax ,%ecx   #高位暫存器加法
      pushl %ecx #高64位
      pushl %edx  #低64位
      push $output
      call printf 
      addl $12,%esp     
      pushl $0
      call exit

       

 

2. 減法

   sub source,destination(適用於低位暫存器)

   其中的destination 的值中減去source的值,結果儲存在destination 

   sbb  source,destination(適用於高位暫存器)

   其中的destination 的值中減去source的值,結果儲存在destination 

  例程:

.section .data
data1:
    .quad 72520551615
data2:
    .quad 5732348928
output:
  .asciz "The result is %d\n"
.section .text
.globl _start
_start:
     nop
     movl data1,%ebx
     movl data1+4,%eax
     movl data2 ,%edx
     movl data2+4 ,%ecx
     subl %ebx,%edx
     sbbl %eax,%ecx
     pushl %ecx
     pushl %edx
     push $output
     call printf 
     addl $12,%esp     
     pushl $0
     call exit

 執行結果:

  

 遞增和遞減指令

 inc destination(遞增) 

dec destination(遞減)

3.乘法

  3.1  mul sourcce(無符號整數)

         用於兩個無符號的整數相乘,source可以是8,16,32位暫存器或者記憶體值。mul的目標數是隱含的,乘法操作中另一個運算元必須存放在AL,AX或EAX暫存器中

 

.section .data
data1:
    .int 315814
data2:
    .int 165432
result:
    .quad 0 
output:
  .asciz "The result is %qd\n"
.section .text
.globl _start
_start:
     nop
     movl data1,%eax  
     mull data2
     movl %eax ,result 
     movl %edx,result+4
     pushl %edx
     pushl %eax
     push $output
     call printf 
     addl $12,%esp     
     pushl $0
     call exit

   

         第17 行程式碼為何選擇edc暫存器。對於32位源值,  目標位置使用64位EDX: EAX暫存器對,高位雙字儲存在EDX暫存器中才低位雙字在EAX暫存器中。當使用MUL的16位或者32位版本時,如果在EDX ( 或者DX)寄器中儲存著資料,那麼一定要把資料儲存到其他位置。

3.2 imul 帶符號整數操作

    imul source (其行為和mul完全一樣)

    imul source destination (結果被限制在單一目標暫存器,小心溢位)

    imul  multiplier, source ,destination(multiplier * source結果存在destinatiuon )

4 除法

   4.1 無符號除法

          div divisor 

 在執行DIV指令之前,被除數必須已經儲存到了AX暫存器(對於16位值)、DX:AX暫存器對(對於32位值)或者EDX:EAX暫存器對(對於64位值)。允許的除數的最大值取決於被除數的長度。對於16位被除數,除數只能是8位;對於32位被除數,除數只能是16位;對於64位被除數,除數只能是32位。除法操作的結果是兩個單獨的數字:商和餘數。這兩個值都儲存在被除數值使用的相同暫存器中。

例程: 

.section .data
dividend:
      .quad 8335
divisor:
       .int 25
quotient:
      .int 0
remainder:
       .int 0
output:
      .asciz "The quotient is %d ,and the remainder is %d\n"
.section .text
.globl _start
_start:
      nop
      movl dividend  ,%eax
      movl dividend+4 ,%edx
      divl divisor 
      movl %eax,quotient 
      movl %edx,remainder 
      pushl quotient
      push $output
      call printf 
      addl $12,%esp     
      pushl $0
      call exit

 執行結果

    

 

     4.2 有符號除法

       idiv divisor 

       對於帶符號整數的除法,餘數的符號總是與被除數的符號相同