标签:改变 visual 转移 tst c语言 程序 nts 原理 输出
一、实验目的
1. 理解80×25彩色字符模式显示原理
2. 理解转移指令jmp, loop, jcxz的跳转原理,掌握使用其实现分支和循环的用法
3. 理解转移指令call, ret, retf的跳转原理,掌握组合使用call和ret/retf编写汇编子程序的方法,掌握 参数传递方式
4. 理解标志寄存器的作用
5. 理解条件转移指令je, jz, ja, jb, jg, jl等的跳转原理,掌握组合使用汇编指令cmp和条件转移指令实 现分支和循环的用法
6. 了解在visual studio/Xcode等环境或利用gcc命令行参数反汇编c语言程序的方法,理解编译器生成 的反汇编代码
7. 综合应用寻址方式和汇编指令完成应用编程
二、实验准备
实验前,请复习/学习教材以下内容:
第9章 转移指令的原理
第10章 call和ret指令
第11章 标志寄存器
三、实验内容
略
四、实验结论
1.实验任务1
首先分析三种样式对应的属性字节,绿色对应02h,绿底红色对应24h,白底蓝色对应71h。
其次根据80×25彩色符号模式,确定出显示的位置。
实验代码:
1 assume cs:code,ds:data 2 3 data segment 4 db ‘welcome to masm!‘ 5 db 2h,24h,71h 6 data ends 7 8 code segment 9 start: 10 mov ax,data 11 mov ds,ax 12 13 mov ax,0B872h 14 mov es,ax 15 16 mov cx,3 ;记录还需要输出的行数 17 mov bx,0 ;记录每个颜色相对于第一个颜色数据的偏移地址 18 19 s0:push cx ;利用栈保存cx的值 20 mov cx,16 21 mov di,0 ;记录字符的偏移地址 22 mov si,0 ;记录一行中字符显示的位置 23 24 s1:mov al,ds:[di] 25 mov ah,ds:[16+bx] 26 mov es:[si],ax 27 add si,2 28 inc di 29 loop s1 30 31 pop cx 32 mov ax,es ;借助寄存器,修改段寄存器中的值,切换到下一行 33 add ax,00ah 34 mov es,ax 35 inc bx 36 loop s0 37 38 mov ax,4c00h 39 int 21h 40 41 code ends 42 end start
实验截图:
2.实验任务2
实验代码:
1 assume cs:code, ds:data 2 data segment 3 str db ‘try‘, 0 4 data ends 5 6 code segment 7 start: 8 mov ax, data 9 mov ds, ax 10 11 mov si, offset str 12 mov al, 2 13 call printStr 14 15 mov ah, 4ch 16 int 21h 17 18 printStr: 19 push bx 20 push cx 21 push si 22 push di 23 24 mov bx, 0b800H 25 mov es, bx 26 mov di, 0 27 s: mov cl, [si] 28 mov ch, 0 29 jcxz over 30 mov ch, al 31 mov es:[di], cx 32 inc si 33 add di, 2 34 jmp s 35 36 over: pop di 37 pop si 38 pop cx 39 pop bx 40 ret 41 42 code ends 43 end start
实验截图:
修改后截图:
回答问题:
(1)line19-22, line36-39,这组对称使用的push、pop,这样用的目的是什么?
答:通过栈保存子程序中会遇到的寄存器的值,防止子程序中修改了相应寄存器的值之后,原来的值无法恢复。
(2)line30的功能是什么?
答:将cx中的值赋值给es:[di]。其中cx中的数据代表字符和它的属性,es:[di]代表显存的对应位置,赋值后可以在屏幕上打印出来。
3.实验任务3
(1)子任务1
1 assume cs:code, ds:data 2 data segment 3 x dw 1984 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 15 mov ah, 4ch 16 int 21h 17 18 num2str: 19 push ax 20 push bx 21 push cx 22 push dx 23 24 mov cx, 0 25 mov bl, 10 26 s1: 27 div bl 28 inc cx 29 mov dl, ah 30 push dx 31 mov ah, 0 32 cmp al, 0 33 jne s1 34 s2: 35 pop dx 36 or dl, 30h 37 mov [di], dl 38 inc di 39 loop s2 40 41 pop dx 42 pop cx 43 pop bx 44 pop ax 45 46 ret 47 code ends 48 end start
调试截图:
(2)子任务2
实验代码:
1 assume cs:code, ds:data 2 data segment 3 x dw 1984 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 15 mov si, offset str 16 mov al, 2 17 call printStr 18 19 mov ah, 4ch 20 int 21h 21 22 num2str: 23 push ax 24 push bx 25 push cx 26 push dx 27 28 mov cx, 0 29 mov bl, 10 30 s1: 31 div bl 32 inc cx 33 mov dl, ah 34 push dx 35 mov ah, 0 36 cmp al, 0 37 jne s1 38 s2: 39 pop dx 40 or dl, 30h 41 mov [di], dl 42 inc di 43 loop s2 44 45 pop dx 46 pop cx 47 pop bx 48 pop ax 49 50 ret 51 52 printStr: 53 push bx 54 push cx 55 push si 56 push di 57 58 mov bx, 0B800H 59 mov es, bx 60 mov di, 0 61 s: mov cl, [si] 62 mov ch, 0 63 jcxz over 64 mov ch, al 65 mov es:[di], cx 66 inc si 67 add di, 2 68 jmp s 69 70 over: pop di 71 pop si 72 pop cx 73 pop bx 74 75 pop ax 76 jmp ax 77 78 code ends 79 end start
实验截图:
改变数字:
4.实验任务4
实验代码:
1 assume cs:code, ds:data 2 data segment 3 str db 80 dup(?) 4 data ends 5 6 code segment 7 start: 8 mov ax, data 9 mov ds, ax 10 mov si, 0 11 12 s1: 13 mov ah, 1 14 int 21h 15 mov [si], al 16 cmp al, ‘#‘ 17 je next 18 inc si 19 jmp s1 20 next: 21 mov cx, si 22 mov si, 0 23 s2: mov ah, 2 24 mov dl, [si] 25 int 21h 26 inc si 27 loop s2 28 29 mov ah, 4ch 30 int 21h 31 code ends 32 end start
实验截图:
回答问题:
(1)line12-19实现的功能是:循环读入字符,当遇到#的时候停止读入,跳转到next段执行子程序。
(2)line21-27实现的功能是:将之前输入的内容输出到屏幕上。
5.实验任务5
1 #include <stdio.h> 2 int sum(int, int); 3 4 int main() { 5 00771760 push ebp 6 00771761 mov ebp,esp 7 00771763 sub esp,0E4h 8 00771769 push ebx 9 0077176A push esi 10 0077176B push edi 11 0077176C lea edi,[ebp-0E4h] 12 00771772 mov ecx,39h 13 00771777 mov eax,0CCCCCCCCh 14 0077177C rep stos dword ptr es:[edi] 15 0077177E mov ecx,offset _45D01272_源@cpp (077C003h) 16 00771783 call @__CheckForDebuggerJustMyCode@4 (0771208h) 17 int a = 2, b = 7, c; 18 00771788 mov dword ptr [a],2 19 0077178F mov dword ptr [b],7 20 21 c = sum(a, b); 22 00771796 mov eax,dword ptr [b] 23 00771799 push eax 24 0077179A mov ecx,dword ptr [a] 25 0077179D push ecx 26 0077179E call sum (077107Dh) 27 007717A3 add esp,8 28 007717A6 mov dword ptr [c],eax 29 30 return 0; 31 007717A9 xor eax,eax 32 }
1 int sum(int x, int y) { 2 007716F0 push ebp 3 007716F1 mov ebp,esp 4 007716F3 sub esp,0C0h 5 007716F9 push ebx 6 007716FA push esi 7 007716FB push edi 8 007716FC lea edi,[ebp-0C0h] 9 00771702 mov ecx,30h 10 00771707 mov eax,0CCCCCCCCh 11 0077170C rep stos dword ptr es:[edi] 12 0077170E mov ecx,offset _45D01272_源@cpp (077C003h) 13 00771713 call @__CheckForDebuggerJustMyCode@4 (0771208h) 14 return (x + y); 15 00771718 mov eax,dword ptr [x] 16 0077171B add eax,dword ptr [y] 17 } 18 0077171E pop edi 19 0077171F pop esi 20 } 21 00771720 pop ebx 22 00771721 add esp,0C0h 23 00771727 cmp ebp,esp 24 00771729 call __RTC_CheckEsp (0771212h) 25 0077172E mov esp,ebp 26 00771730 pop ebp 27 00771731 ret
(1)高级语言中形参列表是从右向左进行入栈的,先将数据存入寄存器中,再进行入栈操作。
(2)调用函数后返回是调用call命令和ret命令进行的。
汇编语言程序设计第四次实验 汇编应用编程和C语言程序反汇编分析
标签:改变 visual 转移 tst c语言 程序 nts 原理 输出
原文地址:https://www.cnblogs.com/nuist-wyy/p/14128736.html