• 汇编学习--第九天


    实验9 根据材料编程

    注意:

    在做第十章课后题时,发现个问题,最上面红框和下面两个红框,对偏移地址000h的叫法不同,我根据实际显示,es:000h叫0行0列(这一行不会在显示器上显示)

    assume cs:codesg,ds:datasg,ss:stacksg
    datasg segment
        db 'welcome to masm!'
        db 02h,24h,71h;三种颜色
    datasg ends
    stacksg segment
        db 16 dup (0)
    stacksg ends
    codesg segment
            ;datasg段地址
    start:    mov ax,datasg
            mov ds,ax
        
            ;stacksg段地址
            mov ax, stacksg
            mov ss,ax
            mov sp,10h
            
            ;目标地址
            mov ax,0b800h
            mov es,ax
            
            mov cx,3
            mov di,10h;在datasg中的偏移量
            mov bx,780h;表示第12行
            ;第一层循环,3种颜色
    s:        mov si,0;在显示缓冲区中的偏移地址
            mov ah,ds:[di]
            push cx
            push di
            
            mov di,0
            mov cx,16
            ;第二层循环,字符串
    s0:        mov al,ds:[di]
            mov es:[bx+si+64],al;低位存字符
            mov es:[bx+si+64+1],ah;高位存属性
            inc di
            add si,2
            loop s0
            
            pop di
            pop cx
            inc di
            add bx,0a0h
            loop s
            
            mov ax,4c00h
            int 21h
    codesg ends
    end start

    要理解材料中的几个点:

    • 1.每行可以表示80个字符,160字节
    • 2.每行的偏移地址规律----起始偏移地址:行数  * 160    结束偏移地址:起始地址+159  (这里都是十进制表示,需要转换为十六进制)
    • 3.属性字节格式,一共8位,每四位对应十六进制的字节的高位和低位。1表示有这个属性,0表示没有。

    概括

    这道题简单的说就是将字符数据属性数据写入b800h(显示缓冲区),并居中显示。

    分步解析

    • 1.要居中,首先行居中为12行开始,根据上面的公式得到起始偏移地址780h,而下一行起始地址就是 原偏移地址+0a0h--0a0h为160字节;
    • 2.列居中,字符串占16字符,总共80字符,还剩64字符,也就是128字节,字符串前后等距,为128/2=64字节,所以需要在偏移地址基础上加64
    • 2.从自定义的datasg段中取字符串和属性数据,字符串写入低位:0b800h:[起始偏移地址+64]   属性写入高位:0b800h:[起始偏移地址+1+64]

    第十章 CALL和RET指令

    10.1 ret和retf

    ret指令:使用栈中数据修改IP,实现近转移

    retf指令:使用栈中数据修改CS和IP,实现远转移

    执行ret相当于是pop IP,将栈顶元素作为IP值

    执行retf相当于pop IP,pop CS,和ret类似

    ret的应用

    assume cs:codesg,ss:stacksg
    stacksg segment
        db 16 dup (0)
    stacksg ends
    codesg segment
            mov ax,4c00h
            int 21h
        
    start:    mov ax,stacksg
            mov ss,ax
            mov sp,10h
            mov ax,0
            push ax
            ret
    codesg ends
    end start

    retf应用

    assume cs:codesg,ss:stacksg
    stacksg segment
        db 16 dup (0)
    stacksg ends
    codesg segment
            mov ax,4c00h
            int 21h
        
    start:    mov ax,stacksg
            mov ss,ax
            mov sp,10h
            mov ax,0
            push cs
            push ax
            retf
    codesg ends
    end start

    检测点 10.1

    assume cs:codesg
    stacksg segment
        db 16 dup (0)
    stacksg ends
    codesg segment
    start:    mov ax,stacksg
            mov ss,ax
            mov sp,10h
            mov ax,1000h
            push ax
            mov ax,0
            push ax
            retf
    codesg ends
    end start

    10.2 call指令

    使用call指令进行两步:

    • 1.将IP或CS和IP压入栈中
    • 2.转移

    call实现转移方法和jmp相似

    10.3 依据位移进行转移的call指令

    call + 标号

    相当于执行

    push ip

    jmp near ptr 标号

    检测点 10.2

    ax=6

    在读入指令call s时,IP首先自动+3(下一个指令偏移地址),所以入栈的数据为6,pop ax也就是ax=6

    assume cs:codesg
    codesg segment
    start:    mov ax,0
            call s
            inc ax
    s:        pop ax
            
            mov ax,4c00h
            int 21h
    codesg ends
    end start

    10.4 转移的目的地址在指令中的call指令

    call far ptr 标号

    相当于执行

    push CS

    push IP

    jmp far ptr 标号

    检测点 10.3

    assume cs:codesg
    codesg segment
            mov ax,4c00h
            int 21h
            
    start:    mov ax,0
            call far ptr s;入栈的IP为8,CS为1000h
            inc ax
    s:        pop ax;ax=8
            add ax,ax;ax=16
            pop bx;bx=1000h
            add ax,bx;ax=1010h
            
            mov bx,0
            push bx
            ret
    codesg ends
    end start

    因为在我的代码中,入栈CS=076AH,IP=DH

    所以

    assume cs:codesg
    codesg segment
            mov ax,4c00h
            int 21h
            
    start:    mov ax,0
            call far ptr s;入栈的IP为dh,CS为076ah
            inc ax
    s:        pop ax;ax=dh
            add ax,ax;ax=1ah
            pop bx;bx=076ah
            add ax,bx;ax=0784h
            
            mov bx,0
            push bx
            ret
    codesg ends
    end start
  • 相关阅读:
    Hadoop WordCount改进实现正确识别单词以及词频降序排序
    两个栈实现一个队列
    数据库弱一致性四个隔离级别
    vs2008生成lib文件
    开始整理资料
    基于AKS素性检测的素数生成器
    生成指定位数的随机数
    Windows 7远程桌面 重启 关机 任务管理器 命令
    摩根IT实习经验谈及其他
    Hadoop下进行反向索引(Inverted Index)操作
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/11167474.html
Copyright © 2020-2023  润新知