实验任务1
1.task1.asm源码
assume cs:code, ds:data data segment x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h data ends code segment start: mov ax, data mov ds, ax mov si, offset x mov di, offset y call add128 mov ah, 4ch int 21h add128: push ax push cx push si push di sub ax, ax mov cx, 8 s: mov ax, [si] adc ax, [di] mov [si], ax inc si inc si inc di inc di loop s pop di pop si pop cx pop ax ret code ends end start
2.问题回答
不能
理由如下,使用add会产生进位,如果用add的话,1就会把cf清零,后面就不能把进位加上。
3.
加法运算前
加法运算后
实验任务2
1.task2.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 ah, 2 mov dl, 0ah int 21h 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
2.运行测试截图
3.问题回答
Line 11-18的功能是判断字符是否等于#
Line 20-22的功能是打印换行
Line 24-30的功能是打印字符串
实验任务3
1.task3.asm源码
assume cs:code, ds:data data segment x dw 91, 792, 8536, 65521, 2021 len equ $- x ; data ends code segment start: mov ax,data mov ds,ax mov si,0 mov cx,5 mov bl,10;除法原理 s1: mov ax,[si]; push cx;保护cx call printNumber pop cx call printSpace add si,2 loop s1; mov ah,4ch int 21h printNumber: mov bx,10 mov cx,0 s2: mov dx,0 ;ax 商 ;dx 余数 div bx;除法 被除数在ax,除数在bx, 商在ax,余数在dx push dx inc cx;记录长度 cmp ax,0;商为0 jne s2;商不为0继续跳s2 s3: ;开始输出 mov ah,2 pop dx or dl,30H;ASCALL编码 int 21h loop s3 ret printSpace: mov ah,2 mov dl,' ' int 21h; ret code ends end start
2.运行截图
实验任务4
1.task4.asm源码
assume cs:code, ds:data data segment str db "assembly language, it's not difficult but tedious" len = $ - str data ends code segment start: mov ax,data mov ds,ax mov si,0 mov cx,len call strupr mov ah,4ch int 21h strupr: ;0100 0001 A ;0110 0001 a s: cmp byte ptr ds:[si],61h jb s2 cmp byte ptr ds:[si],7ah ja s2 mov dl,ds:[si] and dl,11011111B mov ds:[si],dl s2: inc si loop s ret code ends end start
2.调试截图
实验任务5
1.task5.asm源码
assume cs:code, ds:data ;输入7,则屏幕显示yes ;否则输出no data segment str1 db "yes", '$' str2 db "no", '$' data ends code segment start: mov ax, data mov ds, ax ;系统调用,输入字符 mov ah, 1 int 21h ;:设置光标位置(ah) = 2, (bh) = 页号(默认取0), (dh) = 行号, (dl) = 列号 mov ah, 2 mov bh, 0;页号 mov dh, 24;行号 mov dl, 70;列号 int 10h;BIOS中断例程调用 cmp al, '7' je s1;相等跳转 ;不相等输出str mov ah, 9 mov dx, offset str2;str2的偏移地址 ds:data int 21h jmp over ;s1表示等于7,输出yes s1: mov ah, 9;输出字符串 mov dx, offset str1;str1的偏移地址 ds:data int 21h ;over表示结束 over: mov ah, 4ch int 21h code ends end start
2.结果截图
3.回答问题
程序功能是判断输入字符是否为7,如果是7就输出yes,如果不是7就输出no
实验任务6
1.task6_1.asm源码
assume cs:code code segment start: ; 42 interrupt routine install code mov ax, cs mov ds, ax mov si, offset int42 ; set ds:si mov ax, 0 mov es, ax mov di, 200h ; set es:di mov cx, offset int42_end - offset int42 cld ;将标志寄存器Flag的方向标志位DF清零。 rep movsb ;把代码从ds:si复制到es:di中,cx中存放复制的代码长度 ; set IVT(Interrupt Vector Table) mov ax, 0 mov es, ax mov word ptr es:[42*4], 200h mov word ptr es:[42*4+2], 0 mov ah, 4ch int 21h int42: jmp short int42_start str db "welcome to 2049!" len equ $ - str ; display string "welcome to 2049!" int42_start: mov ax, cs mov ds, ax mov si, 202h mov ax, 0b800h mov es, ax mov di, 24*160 + 32*2 mov cx, len s: mov al, [si] mov es:[di], al mov byte ptr es:[di+1], 2 inc si add di, 2 loop s iret ;CPU回到执行中断处理程序前的执行点继续执行程序 int42_end: nop code ends end start
2.task6_2.asm源码
assume cs:code code segment start: int 42 ; 调用自己实现的42号软中断 mov ah, 4ch int 21h code ends end start
3.通过实验对中断的理解
中断是打断CPU正常的指令执行顺序转而去执行位置的指令的行为。非常类似于CPU不听使唤的执行了一个CALL指令的样子。中断主要由三部分组成,中断号 、中断向量表、中断程序程序。
1)中断号指明要去执行什么程序,
2)中断向量表表明这个程序存放的位置。
3)中断向量表存放在内存开始处,即地址为 0的地方,中断向量表每一项包含4字节,前两字节是偏移地址,后两字节是段地址,共256个中断向量,所以中断向量表占用内存为1K。
所以假设触发了中断号是 N的中断,那么在中断向量表偏移地址N*4的位置就存储着处理这个中断的程序的地址。所以实际上完全可以通过修改中断向量表来实现自己的中断处理程序。
INT 中断是固化在主板的ROM中的BIOS系统提供的用于代码和硬件交互的程序集合,其实将 INT触发的软中断理解成主板(BIOS)提供的API函数即可,实际上它和call指令也没啥区别,只不过call指令跟的是地址int指令跟的是中断编号,cpu自动将中断编号对照中断表转换成指定的中断例程地址。