# 实验八,九

实验八

  1. 分析下面的程序,在运行前思考:这个程序可以正确返回吗?
    运行后再思考:为什么是这种结果?
    通过这个程序加深对相关内容的理解。

    assume cs:codesg
    
    codesg segment
    	mov ax,4c00h
    	int 21h
    
    start:
    	mov ax,0
    s:
       	nop
       	nop
    
       	mov di,offset s
       	mov si,offset s2
       	mov ax,cs:[si]
       	mov cs:[di],ax
       	; 将s2处的jmp指令传给s处
       	; 而且nop指令码占一个字节,jmp指令占两个字节,运行后两个nop变成一个jmp
       	; 而且注意jmp指令是jmp short,是通过相对位移进行转移,表面上是转移到s1,实际上是转移到相对地址-10处,若jmp short s1指令所在位置为076a:0020,转移后位置是076a:0018,相差 20h+ 02h(ip此时已经指向下一条指令) - 18h = 0ah,也就是10。因此,s处的地址是076a:0008,其下一条指令为076a:00a0,减去10之后,为076a:0000,对应代码段开始的两条指令,mov ax,4c00h和int 21h,程序得以正常结束。
    
    s0:
    	jmp short s
    
    s1:
    	mov ax,0
    	int 21h
    	mov ax,0
    
    s2:
    	jmp short s1
    	nop
    
    codesg ends 
    end start		
    

    答: 解释已在题目中。本题唯一要注意的就是 jmp 指令码中 存的是相对位移,而不是绝对地址,因此复制到其他位置后,执行转移也是通过相对位移

    实验九

    编程:在屏幕中间分别显示绿色、绿底红字、白底蓝字的字符串 ' Welcome to masm ' 。

    assume cs:codesg,ds:datasg,ss:stacksg
    datasg segment
    	db 'welcome to masm'
    	db 02h,24h,71h  ;定义了三种颜色,绿色、绿底红字、白底蓝字
    datasg ends
    stacksg segment
    	dw 10 dup(0)
    stacksg ends 
    codesg segment
    	start:
    	mov ax,datasg
    	mov ds,ax
    	mov ax,stacksg
    	mov ss,ax
    	mov ax,0b872h; 屏幕中央开始输出字符串,显示器可以显示25行,每行80个字符,每个字符两个字节
    	;160*12(定位到中间那一行)+32*2(32是因为字符串共15个字节,一行80个字节,字符串处于中间的话要从第32个字节开始输出)
    	mov es,ax; es容易忘记这个寄存器
    	mov cx,3
    	mov bx,15
    	mov di,0
    	; 外层循环用来输出三行字符串
    	s:
    	push cx
    	
    	mov cx,15
    	mov si,0
    	push di; 将每行开头位置保存,用来换行
    	; 内层循环用来输出单个字符串
    	s1:
    	mov al,[si]
    	mov ah,[bx]
    	mov es:[di],ax; 将字符ascii和格式组合在一起传递
    	inc si
    	add di,2
    	loop s1
    
    	pop di
    	pop cx
    	inc bx
    	add di,0a0h; 换下一行
    	loop s
    
    	mov ax,4c00h
    	int 21h
    
    codesg ends
    end start
    
posted @ 2023-07-16 14:39  三年、  阅读(30)  评论(0)    收藏  举报