汇编实验

汇编实验

  • 说是实验,实际就是写一下书上的题罢了,对应标号的basis部分,下面直接上问题和代码
  • 关于64位编程,之后会专门更相关的博客,目前是32位编程

整数数组求和

L2循环的方法我是想仿照C的写法写的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.386
.model flat,stdcall
.stack 4096
ExitProcess proto ,dwExitCode:DWORD

.data
intArray DWORD 10000h,2000h,30000h,40000h
i DWORD 0;
.code
main proc
mov edi, OFFSET intArray
mov ecx, LENGTHOF intArray
mov eax, 0
L1:
add eax, [edi]
add edi, TYPE intArray
loop L1

mov edi, OFFSET intArray
mov ecx, LENGTHOF intArray
mov eax, 0
L2:
mov ebx, i
imul ebx, ebx ,TYPE intArray
add eax, intArray[ebx]
inc i
loop L2
invoke ExitProcess,0
main ENDP
END main

注意为了节省位置,下面的都不再添加程序的头尾内容,只有.data和.code

复制字符串

需要注意的是,无法直接内存复制过去,需要转经寄存器,逐位复制即可

1
2
3
4
5
6
7
8
9
10
11
12
13
.data 
source BYTE "This is the source string",0
target BYTE SIZEOF source DUP(0)

.code
mov esi, 0 ;变址寄存器
mov ecx, LENGTHOF source

L1:
mov al, source[esi]
mov target[esi], al
inc esi
loop L1

数组操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
.data
intarray DWORD 1,2,3,4,5,6,7,8,9,10
myarray DWORD 1,2,3,4,5,6,7,8,9,10
len DWORD LENGTHOF intarray

.code
;数组反向,intarray
mov edi, OFFSET intarray
mov ecx, len
mov edi, ecx ; 尾部索引
mov esi, 0 ; 头部索引
dec edi ; 索引是数目-1
L1:
mov ecx, edi
sub ecx, esi
mov eax, intarray[esi * TYPE intarray] ;从头开始的数
mov ebx, intarray[edi * TYPE intarray] ;从尾开始的数
mov intarray[esi * TYPE intarray], ebx
mov intarray[edi * TYPE intarray], eax

dec edi ; 尾部向前
inc esi ; 头部向后
loop L1

;数组元素移位,myarray
;将32位整数数组元素的位置逐个向右移动一位,最后一个移动到第一个数
mov esi, LENGTHOF myarray
dec esi
mov ecx, esi ;移动过最后一个了,少循环一次
mov eax, myarray[esi * TYPE myarray]
mov ebx, myarray[0]
mov myarray[0], eax ;最后一个数移动到第一个
mov esi, 0 ;从零开始计数
L2:
inc esi ;目的位置
mov eax, myarray[esi * TYPE myarray] ;保存目的位置的数
mov myarray[esi * TYPE myarray], ebx ;移动
mov ebx ,eax
loop L2

  • mov edi, OFFSET intarray这句话的目的是方便我调试的时候看到数组位置,在内存中找到,观察结果是否正确
  • 数组反向我只想到了这个方法,有空借鉴一下网上的方法,目前还待优化,奇数次会进行一次没有意义的循环(自己和自己交换一下)

斐波那契数列求和

编写汇编程序,计算斐波那契数列前7项的和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.data
Fibo1 DWORD 1
Fibo2 DWORD 1

.code
mov eax, Fibo1
mov ebx, Fibo2
mov ecx, 7
mov esi, 0 ; 最终结果放入esi
fiboSum:
add esi, eax ; 累加一项
mov edx, eax
add edx, ebx ; 算出数列下一项
mov eax, ebx
mov ebx, edx ; 后移
loop fiboSum
  • 没啥困难的,我们每次加一个数,算出下一个数,重复7次就行

附录

  • 调试方法:
    打下断点后打开调试,在菜单栏调试中选择窗口,再选寄存器,内存,在寄存器的窗口出右击,可以控制显示什么,目前用到的可以调出来cpu标志位

  • 对应

书上的 别名 别名
溢出标志OF(Over flow flag) OV(1) NV(0)
方向标志DF(Direction flag) DN(1) UP(0)
中断标志IF(Interrupt flag) EI(1) DI(0)
符号标志SF(Sign flag) NG(1) PL(0)
零标志ZF(Zero flag) ZR(1) NZ(0)
辅助标志AF(Auxiliary carry flag) AC(1) NA(0)
奇偶标志PF(Parity flag) PE(1) PO(0)
进位标志CF(Carry flag) CY(1) NC(0)
  • 图示

调试参考图1
调试参考图2
调试参考图3

Author

Ctwo

Posted on

2019-07-20

Updated on

2020-10-25

Licensed under

Comments