实验4 汇编应用编程和c语言程序反汇编分析
1. 实验任务1
教材「实验9 根据材料编程」(P187-189)
编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串'welcome to masm!'。
结果如下:
代码:
1 assume cs:code, ds:data 2 data segment 3 db 'welcome to masm!' ;需要显示的字符 4 db 02h,24h,71h ;颜色的16进制表示,00000010b,00100100b,01110001b 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 12 mov ax,0b800h;设置显存地址 13 mov es,ax 14 15 mov di,1824;三句话中第一行字m所在列的偏移地址 16 mov bx,16 ;颜色的数据存放在字母的后面,在数据段的16个字节 17 mov cx,3;三行数据,循环3次 18 19 s: push cx;存储外层循环 20 mov si,0 21 mov cx,16;内存循环 22 23 s1: mov al,ds:[si];低字节存储字符ASCII码 24 mov ah,ds:[bx];高字节存储字符属性 25 mov es:[di],ax 26 add di,2 27 inc si 28 loop s1 29 30 pop cx;取出外循环 31 inc bx 32 add di,128;从上一行的'!'转到下一行的'w',因为每个字符包含字符的属性,所以一行字占32字节 33 loop s 34 35 mov ah, 4ch 36 int 21h 37 code ends 38 end start
实现思路:在显存区域,以字符为单位显示,高位存储属性,地位存储ASCII码,因此该题目所占内存为32字节,一行为160个,所以在中间位置的话是64-96;
整屏幕共25行,所在行数为11-13,所以其实位置为11*160+64=1824;设置两个循环,来实现三行打印和遍历16个字母,;cx寄存器不够用,因此使用栈存储。
2. 实验任务2
编写子程序printStr,实现以指定颜色在屏幕上输出字符串。调用它,完成字符串输出。
运行结果:
修改代码之后的运行结果:
基于运行结果,理解源代码,以及,组合使用转移指令call和ret实现子程序的原理与方法。具体地,在
line18-40中:
line19-22, line36-39,这组对称使用的push、pop,这样用的目的是什么?
答:该程序调用子程序,为了不改变源程序中各个寄存器的值,先压栈保存在弹出了以便主程序后面使用。
line30的功能是什么?
答:将16位寄存器的值写入显存,显示在屏幕上。
3. 实验任务3
使用任意文本编辑器,录入汇编源程序task3.asm。
1 assume cs:code, ds:data 2 data segment 3 x dw 1999 4 str db 16 dup(0) 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 mov ax, x 12 mov di, offset str 13 call num2str 14 mov si, offset str 15 mov al, 2 16 call printStr 17 mov ah, 4ch 18 int 21h 19 20 num2str: 21 push ax 22 push bx 23 push cx 24 push dx 25 26 mov cx, 0 27 mov bl, 10 28 s1: 29 div bl 30 inc cx 31 mov dl, ah 32 push dx 33 mov ah, 0 34 cmp al, 0 35 jne s1 36 s2: 37 pop dx 38 or dl, 30h 39 mov [di], dl 40 inc di 41 loop s2 42 43 pop dx 44 pop cx 45 pop bx 46 pop ax 47 48 ret 49 50 51 printStr: push bx 52 push cx 53 push si 54 push di 55 mov bx, 0b800H 56 mov es, bx 57 mov di, 0 58 59 s: mov cl, [si] 60 mov ch, 0 61 jcxz over 62 mov ch, al 63 mov es:[di], cx 64 inc si 65 add di, 2 66 jmp s 67 68 over: pop di 69 pop si 70 pop cx 71 pop bx 72 ret 73 code ends 74 end start
子任务1
对task3.asm进行汇编、链接,得到可执行程序后,在debug中使用u命令反汇编,使用g命令执行
到line15(程序退出之前),使用d命令查看数据段内容,观察是否把转换后的数字字符串'1984'存放
在数据段中str标号后面的单元。
-g命令运行到15行(退出去之前)结果截图:
子任务2
对task3.asm源代码进行修改、完善,把task2.asm中用于输出以0结尾的字符串的子程序加进来,
实现对转换后的字符串进行输出。
把task3.asm源代码中,line3中整数改成0~2559之间的任意数值,运行测试,观察结果。
4. 实验任务4
使用任意文本编辑器,录入汇编源程序task4.asm。
assume cs:code, ds:data data segment str db 80 dup(?) data ends code segment start: mov ax, data mov ds, ax mov si, 0 s1: mov ah, 1 int 21h mov [si], al cmp al, '#' je next inc si jmp s1 next: mov cx, si mov si, 0 s2: mov ah, 2 mov dl, [si] int 21h inc si loop s2 mov ah, 4ch int 21h code ends end start
汇编、链接、运行程序,输入一个字符串并以#结束(比如,2020, bye#)观察运行结果。
line12-19实现的功能是?
答:将键盘键入的字符存入es寄存器,知道碰到#跳转到next部分,结束程序。
line21-27实现的功能是?
答:将键入的数据存入显存,显示在屏幕上。
5. 实验任务5
在visual studio集成环境中,编写一个简单的包含有函数调用的c程序。代码如下:
设置断点
反汇编
调用参数时是将参数先压栈,压栈的顺序不同的编译器会有区别,本例中从右到左,再使用call调用子程序,
程序调用完毕后,结果保存在eax中,当做返回值。