彙編基本的數學運算

整數運算

  • 加法
    • 加法指令
      add source, destination
    • 示例
# addtest1.s - An example of the ADD instruction
.section .data
data:
	.int 40
.section 
.globl _start
_start:
	nop
	movl $0, %eax
	movl $0, %ebx
	movl $0, %ecx
	movb $20, %al
	addb $10, %al
	movsx %al, %eax
	movw $100, %cx
	addw %cx, %bx
	movsx %bx, %ebx
	movl $100, %edx
	addl %edx, %edx
	addl data, %eax
	addl %eax, data
	movl $1, %eax
	movl $0, %ebx
	int $0x80
  • 發現一個進位或者溢出
    • 示例
# addrest.s - An example of detecting a carry condition
.section .text
.globl _start
_start:
	nop
	movl $0, %eax
	movb $190, %bl
	movb $100, %al
	addb %al, %bl
	jc over
	movl $1, %eax
	int $0x80
over:
	movl $1, %eax
	movl $0, %ebx
	int $0x80	
* ADC 指令
	* 格式
		adc source, destination
	* 示例
# addtest.s - An example of using the ADC instruction
.section .data
data1:
	.quad 7252051615
data2:
	.quad 5732348928
output:
	.asciz "The result is %qd\n"
.section .text
.globl  _start
_start:
	movl data1, %ebx
	movl data1+4, %eax
	movl data2, %edx
	movl data2+4, %ecx
	addl %ebx, edx
	adcl %eax, %ecx
	pushl %ecx
	pushl %edx
	push $output
	call printf
	add $12, %esp
	pushl $0
	call exit
  • 減法
    • 減法指令
      • 格式
        sub source, destionation
      • 示例
# subtest.s - An example of the SUB instruction
.section .data
data:
	.int 40
.section .text
.globl _start
_start:
	nop
	movl $0, %eax
	movl $0, %ebx
	movl $0, %ecx
	movb $20, %al
	subb $10, %al
	movsx %al, %eax
	movw $100, %cx
	subw %cx, %bx
	movsx %bx, %ebx
	movl $100, %edx
	subl %eax, %edx
	subl data, %eax
	subl %eax, data
	movl $1, %eax
	movl $0, %ebx
	int $0x80
* 減法的進位和溢出標誌
	* 示例
# subtest.s - An example of a subtraction carry
.section .text
.globl _start
_start:
	nop
	movl $5, %eax
	movl $2, %ebx
	subl %eax, %ebx
	jc under
	movl $1, %eax
	int $0x80
under:
	movl $1, %eax
	movl $0, %ebx
	int $0x80
* SBB 指令
	* 標誌
		sbb source, destiantion
	* 示例
# sbbtest.s - An example of using the SBB instruction
.section .data
data1:
	.quad 7252051615
data2:
	.quad 5732348928
output:
	.asciz "The result is %qd\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
	add $12, %esp
	push $0
	call exit
* 加一和減一指令
	* 格式
		dec destionation
		inc destionation
  • 乘法
    • 無符號乘法
      • 格式
        mul source
源操作數大小 目的操作數 結果存放
8 bits AL AX
16 bits AX DX:AX
32 bits EAX EDX:EAX
* 示例
# multest.s - An example of using the MUL instruction
.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
	pushl $output
	call printf
	add $12, %esp
	pushl $0
	call exit
* 有符號整數乘法
	* 格式
		imul source
		imul source, destination
		imul multiplier, source, destionation
	* 示例
# imultest.s - An example of the IMUL instruction formats
.section .data
value1:
	.int 10
value2:
	.int -35
value3:
	.int 400
.section .text
.globl _start
_start:
	nop
	movl value1, %ebx
	movl value2, %ecx
	imull %ebx, %ecx
	movl $1, %eax
	movl $0, %ebx
	int $0x80
* 發現溢出
# imultest. s - An example of detecting an IMUL overflow
.section .text
.globl _start
_start:
	nop
	movw $680, %ax
	movw $100, %cx
	imulw %cx
	jo over
	movl $1, %eax
	movl $0, %ebx
	int $0x80
over:
	movl $1, %eax
	movl $1, %ebx
	int $0x80
  • 除法
    • 無符號除法
      • 格式
        div divisor
被除數 大小 餘數
AX 16 bits AL AH
DX:AX 32 bits AX DX
EDX:EAX 64 bits EAX EDX
* 示例
# divtest.s - An example of the DIV instruction
.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 remainder
	pushl quotient
	pushl $output
	call printf
	add $12, %esp
	pushl $0
	call exit
* 有符號除法
	* 格式
		idiv divisor

移位運算

  • 通過移位進行乘法運算
    • 格式
      sal destination
      sal %cl, destination
      sal shifter, destination
    • 示例
# saltest.s - An example of the SAL instruction
.section .data
value1:
	.int 25
.section .text
.globl _start
_start:
	nop
	movl $10, %ebx
	sall %ebx
	movb $2, %cl
	sall %cl, %ebx
	sall $2, %ebx
	sall value1
	sall $2, value1
	movl $1, %eax
	movl $0, %ebx
	int $0x80
  • 通過移位進行除法運算
    • 格式
      SAR (使用符號位)
      SHR (使用0)
  • 循環移位
指令 描述
ROL 循環左移
ROR 循環右移
RCL 包含符號位左移
RCR 包含符號位右移

十進制運算

  • 非壓縮BCD運算
    • 格式
      AAA: 調整加法運算的結果
      AAS: 調整減法運算的結果
      AAM: 調整乘法運算的結果
      AAD: 準備除法運算的被除數

      AAA、AAS、AAM的結果默認放在AL寄存器
      AAD默認被除數存放在AX寄存器

    • 示例

# aaatest.s - An example of using the AAA instruction
.section .data
value1:
	.byte 0x05, 0x02, 0x01, 0x08, 0x02
value2:
	.byte 0x03, 0x03, 0x09, 0x02, 0x05
.section .bss
	.lcomm sum, 6
.section .text
.globl _start
_start:
	nop
	xor %edi, %edi
	movl %5, %ecx
	clc
loop1:
	movb value1(, %edi, 1), %al
	adcb value2(, %edi, 1), %al
	aaa
	movb %al, sum(, %edi, 1)
	inc %edi
	loop loop1
	adcb $0, sum(, %edi, 4)
	movl $1, %eax
	movl $0, %ebx
	int $0x80
  • 壓縮BCD運算
    • 格式
      DAA 調整的ADD或ADC的結果
      DAS 調整SUB或SBB的結果
    • 示例
# dastest.s - An example of using the DAS instruction
.section .data
value1:
	.byte 0x25, 0x81, 0x02
value2:
	.byte 0x33, 0x29, 0x05
.section .bss
	.lcomm result, 4
.section .text
.globle _start
_start:
	nop
	xor %edi, %edi
	movl $3, %ecx
loop1:
	movb value2(, %edi, 1), %al
	sbbb value1(, %edi, 1), %al
	das
	movb %al, result(, %edi, 1)
	inc %edi
	loop loop1
	sbbb $0, result(, %edi, 4)
	movl $1, %eax
	movl $0, %ebx
	int $0x80

邏輯運算

  • 布爾運算
    • AND
    • NOT
    • OR
    • XOR
  • 位測試
    • 示例
# cpuidtest.s - An example of using the TEST instruction
.section .data
output_cpuid:
	.asciz "This processor supports the CPUID instruction\n"
output_nocpuid:
	.asciz "This processor does not support the CPUID instruction\n"
.section .text
.globl _start
_start:
	nop
	pushfl
	popl %eax
	movl %eax, %edx
	xor $00200000, %eax
	pushl %eax
	popfl
	pushfl
	popl %eax
	xor %edx, %eax
	test $00200000, %eax
	jnz cpuid
	pushl $output_nocpuid
	call printf
	add $4, %esp
	pushl $0
	call exit
cpuid:
	pushl $output_cpuid
	call printf
	add $4, %esp
	pushl $0
	call exit
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章