对应basis-3的内容
Irvine32链接库
配置
首先准备好一个配置好masm的项目(正常可以写汇编的),下载好Irvine32(我的在D盘Irvine目录下D:\Irvine)
然后对project右键属性:
- 链接器附加库目录中加入你安装好的路径(D:\Irvine;)
- 链接器输入附加依赖项中加入Irvine32.lib(用32位,别忘了分号隔开)
- 在Microsoft Macro Assemble中的include Paths 加上你的路径(D:\Irvine;)
库测试1:整数IO操作
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| ; 库测试,整数IO操作
include Irvine32.inc
.data count = 4 BlueTextOnGray = blue + (lightGray * 16) DefaultColor = lightGray + (black * 16) arrayD SDWORD 12345678h,1A4B2000h, 3434h, 7AB9h prompt BYTE "Enter a 32-bit signed integer", 0
.code main PROC ; 选择浅灰背景蓝色文本
mov eax, BlueTextOnGray call SetTextColor call Clrscr ; 清屏
; 用DumpMen显示数组
mov esi, OFFSET arrayD ; 开始位置 mov ebx, TYPE arrayD ; 双字 mov ecx, LENGTHOF arrayD ; 单元数 call DumpMem ; 显示内存
; 请求用户输入一组有符号整数
call Crlf ; 显示一个新空白行 mov ecx, COUNT L1: mov edx, OFFSET prompt call WriteString call ReadInt ; 输入数据存入EAX call Crlf
; 用十进制, 十六进制, 二进制显示
call WriteInt ; 显示为有符号十进制 call Crlf call WriteHex ; 显示为十六进制 call Crlf call WriteBin ; 显示为二进制数 call Crlf call Crlf loop L1
; 返回控制台窗口的默认颜色
call WaitMsg ; "Press any key..." mov eax, DefaultColor call SetTextColor call Clrscr
exit main ENDP
END main
|
- DumpMem在控制台窗口中用16进制显示一段内存,其参数为:ESI存储内存区域首地址,ECX存放单元个数,EBX存放单个单元的大小
- SetTextColor设置输出文本的前景色和背景色,颜色常量在Irvine32.inc中定义,要获得完整的颜色字节数值,将背景色乘16加上前景色,如下表示蓝色背景输出黄色字符:
yellow + (blue * 16)
- WriteInt/Bin/Hex 用的都是EAX, 而WriteChar用的是AL
- WriteString向操作台窗口输出一个以空字节结束的字符串,过程中EDX传递偏移量
库测试2:生成随机数
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 41 42 43 44 45 46 47
| include Irvine32.inc Tab = 9 ; Tab的ASCII码
main PROC call Randomize ; 初始化随机生成器 call Rand1 call Rand2 call WaitMsg exit main ENDP
Rand1 PROC ; 生成10个伪随机数 mov ecx, 10 ; 循环10次
randLoop: call Random32
call WriteDec ; 无符号十进制形式输出 mov al, Tab ; 水平制表符 call WriteChar ; 输出制表符 loop randLoop
call Crlf ret Rand1 ENDP
Rand2 PROC ; 生成-50 -- +49之间的10个伪随机数 mov ecx, 10
randLoop: mov eax, 100 ; 指定数值范围0-99 call RandomRange ; 生成随机数 sub eax, 50 ; 数值返回-50至49 call WriteInt ; 用有符号十进制的方式输出 mov al, Tab call WriteChar loop randLoop
call Crlf ret Rand2 ENDP
END main
|
- 我们不需要完全记住每个的用法,需要的时候查查就行了
- Randomize过程对Random32和RandomRange过程的第一个种子进行初始化,种子等于一天中的时间,精度为1/100秒,每当调用Random32和RandomRange的程序运行时,保证生成的序列都不相同
练习题
随机字符串
创建过程生成长度为L的随机字符串,字符全为大写。调用过程时用EAX传递长度为L的值,并传递一个指针指向用于保存该随机字符串的字节数组。编写测试程序调用10次,输出在控制台窗口
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 41 42 43 44 45 46 47 48 49 50 51 52 53
| include Irvine32.inc
.data arrayB BYTE 50 DUP(?) pointer DWORD OFFSET arrayB prompt BYTE "Please Enter the length of random string( < 50 ): ", 0
.code ;---------------------------------------------------------- ; 参数 EAX = 生成随机字符串长度 pointer 指向数组的指针 ; 用于随机生成指定长度的大写字符串 ; 无返回值 generateString PROC mov ecx, eax ; 指定循环次数 call Randomize mov esi, pointer L1: mov eax, 27 ; 范围0--26 call RandomRange add eax, 41h mov [esi], al ; 存入内存 inc esi loop L1 ret generateString ENDP
randString PROC mov edx, OFFSET prompt ; 参数为EDX,表示偏移量 call WriteString call ReadInt ; 读入EAX call Crlf push eax ; 保存有效长度 call generateString pop ecx ; 指定输出循环次数 mov esi, pointer L2: mov al, BYTE PTR [esi] call WriteChar inc esi loop L2 ret randString ENDP
main PROC call randString call Crlf call WaitMsg exit main ENDP
END main
|
- RandomRange 产生的随机数结过会被保存在EAX中, 范围指定也需要EAX,所以每次loop时要重新给EAX赋值
- WriteChar 使用al里的数写成字符, 我们使用PTR将高位数赋给低位寄存器(我寻思直接赋EAX也可以)
递归过程
编写程序调用一个递归过程,过程中对计数器自增来计数,向ECX输入一个值来控制递归次数,只使用loop,不使用后续的条件判断语句
斐波那契生成器
编写一个过程生成含有N个数的斐波那契数列,并将其保存在一个双字数组中,输入参数为双字数组指针和生成个数的计数器。
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 41 42 43 44 45 46 47
| include Irvine32.inc .data fiboArray DWORD 20 DUP(?) p DWORD OFFSET fiboArray
.code ;----------------------------- ; 参数 ECX: 生成多少位斐波那契数, p: 存储数组指针 ; 生成首两位为1的斐波那契数列 ; 无返回 Fibo PROC mov eax, 1 mov ebx, 1 mov esi, p ; 间接寻址 mov [esi], eax add esi, TYPE p mov [esi], ebx add esi, TYPE p sub ecx, 2
generateFibo: mov edx, eax add edx, ebx mov eax, ebx mov ebx, edx mov [esi], edx add esi, TYPE p loop generateFibo ret Fibo ENDP
main PROC mov ecx, 20 call Fibo mov ecx, LENGTHOF fiboArray mov ebx, TYPE fiboArray mov esi, OFFSET fiboArray call DumpMem call Crlf call WaitMsg exit main ENDP
END main
|