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 

       对于带符号整数的除法,余数的符号总是与被除数的符号相同

猜你喜欢

转载自blog.csdn.net/weixin_42528089/article/details/83713351
今日推荐