zoukankan      html  css  js  c++  java
  • 汇编实验十:编写子程序

    预备知识:

    (1)

    ret  :修改IP  IP = SS*16 + SP   SP+=2

    retf :修改CS,IP  IP = SS*16 + SP ,SP+=2 , CS = SS*16 + SP , SP+=2

    Source Code:

    assume cs:code
    
    stack segment
        db 16 dup (0)
    stack ends
    
    code segment
        mov ax,4c00H
        int 21H
    
        start:
            mov ax,stack
            mov ss,ax
            mov sp,16
            mov ax,0
            push ax
            mov bx,0
            ret
    code ends
    end start
    View Code

    IP指向了栈顶元素,栈顶元素等于0,那么下一条命令就是返回程序;

    Source Code:

    assume cs:code
    
    stack segment
        db 16 dup (0)
    stack ends
    
    code segment
        mov ax,4c00h
        int 21h
    start:
        mov ax,stack
        mov ss,ax
        mov sp,16
        mov ax,0
        push cs
        push ax
        mov bx,0
        retf
    code ends
    end start
    View Code

    IP还是指向栈顶元素,下一条命令是返回程序;

    也就是说,

    ret 相当于 pop IP;

    retf 相当于 pop IP,pop CS;

    (2)call:内存中转移

    call word ptr 相当于 push IP,jmp word ptr

    call dword ptr 相当于 push CS,push IP,jmp dword ptr

    Source Code:

    assume cs:code
    
    stack segment
        dw 8 dup (0)
    stack ends
    
    code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,16
        mov ds,ax
        mov ax,0
        call word ptr ds:[0EH]
        inc ax
        inc ax
        inc ax
        mov ax,4c00H
        int 21H
    code ends
    end start
    View Code

    (3)mul,乘法指令

    1、8位,一个数在AL中,一个在内存中,结果在AX中

    2、16位,一个在AX中,一个在内存中,结果,高位在DX中,低位在AX中;

    (4)call和ret的配合:模块化程序

     Source Code:

    assume cs:code
    
    data segment
        dw 1,2,3,4,5,6,7,8
        dd 0,0,0,0,0,0,0,0
    data ends
    
    code segment
    start:
        mov ax,data
        mov ds,ax
        mov si,0
        mov di,16
    
        mov cx,8
        s:
            mov bx,[si]
            call cube
            mov [di],ax
            mov [di].2,dx
            add si,2
            add di,4
            loop s
    
        mov ax,4c00H
        int 21H
    cube:
        mov ax,bx
        mul bx
        mul bx
        ret
    code ends
    end start
    View Code

    (5)批量数据传递,放到内存中,或者栈中;

     Source Code:

    assume cs:code
    
    data segment
        db 'conversation'
    data ends
    
    code segment
    start:
        mov ax,data
        mov ds,ax
        mov si,0
        mov cx,12
        call capital
        mov ax,4c00h
        int 21h
    
    capital:
        and byte ptr [si],11011111b
        inc si
        loop capital
        ret
    code ends
    end start
    View Code

    (6)解决寄存器的冲突,就是将子程序用到的寄存器入栈;

    Source Code:

    assume cs:code
    
    data segment
        db 'word',0
        db 'unix',0
        db 'wind',0
        db 'good',0
    data ends
    
    code segment
    start:
        mov ax,data
        mov ds,ax
        mov bx,0
    
        mov cx,4
        s:
            mov si,bx
            call capital
            call change
            add bx,5
            loop s
        mov ax,4c00h
        int 21h
    
        capital:
            push cx
            push si
        change:
            mov cl,[si]
            mov ch,0
            jcxz ok
            and byte ptr [si],11011111b
            inc si
            jmp short capital
    
        ok:
            pop si
            pop cx
            ret
    code ends
    end start
    View Code

    试验任务:

    显示字符串(注意DOS下一列占两个字符)

    Source Code:

    assume cs:code
    
    data segment
        db 'I am TreeDream!',0
    data ends
    
    code segment
    start:
        mov dh,8
        mov dl,3
        mov cl,2
    
        mov ax,data
        mov ds,ax
        mov si,0
    
        call show_str
    
        mov ax,4c00H
        int 21H
    
    show_str:
        push dx
        push cx
        push ax
        push ss
        push si
    
        mov ax,0B800H
        mov es,ax   ;用于显示的栈段
    
        mov al,0a0h
        dec dh      ;行数以0标号
        mul dh      ;行的偏移
        mov bx,ax
    
        mov al,2    ;dos显示一列占两个字节
        dec dl
        mul al
        add bx,ax   ;显示的起始地址计算完
    
        mov di,0    ;数据段指针
        mov si,0
    
        mov al,cl   ;cx用于循环
    
    s:
        mov ch,0
        mov cl,ds:[di]
        jcxz ok     ;判断cx是否为0
        mov ch,al
        mov es:[bx+si],cx   ;显示
    
        add si,2
        inc di
        jmp short s
    ok:
        pop si
        pop ss
        pop ax
        pop cx
        pop dx
        ret
    code ends
    end start
    View Code

     

    (2)除法溢出

    assume cs:code,ss:stack
    
    stack segment
        dw 8 dup (0)
    stack ends
    
    code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,16
    
        mov ax,1000H
        mov dx,1
        mov bx,1
        div bx
    
        mov ax,4c00h
        int 21h
    
    code ends
    end start
    View Code

    除法的结果超过16为,ax中存不下;

    解决方案,公式是X/N = int(H/N)*65536 + (rem(H/N)*65536 + L) / N

    公式很好理解,但是程序不是很好理解;

    Source Code:

    assume cs:code,ss:stack
    
    stack segment
        dw 8 dup (0)
    stack ends
    
    code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,16
    
        mov ax,4240H
        mov dx,00fH
        mov cx,0aH
        call divdw
    
        mov ax,4c00h
        int 21h
    divdw:
        push ax
        mov ax,dx
        mov dx,0
        div cx
    
        mov bx,ax
        pop ax
        div cx
    
        mov cx,dx
        mov dx,bx
        ret
    
    
    code ends
    end start
    View Code

     

    第一次除法:

    ax = 1,dx = 5

     第二次除法的时候,第一次的除法余数将是第二次除法的高位

    (3)数值显示

    Source Code:

    assume cs:code
    
    data segment
        db 10 dup (0)
    data ends
    
    stack segment
        dw 8 dup(0)
    stack ends
    
    code segment
    start:
        mov ax,42243
        mov bx,data
        mov ds,bx
        mov bx,stack
        mov ss,bx
        mov sp,10h
        mov si,0
        call dtoc
    
        mov dh,8
        mov dl,3
        mov cl,2
        call show_str
        mov ax,4c00h
        int 21h
    
    dtoc:
        push ax
        push bx
        push si
        mov bx,10
        mov si,0
    
    s0:
        mov dx,0
        div bx  ;dx 余数,ax商
        add dx,30h  ;余数入栈
        push dx
        mov cx,ax   ;一直除到商为0
        inc si
        inc cx      ;每次循环cx会减1,然而cx是用来存商的;
        loop s0
    
        mov cx,si   ;cx循环次数,即有多少位
        mov si,0
    s1:
        pop ds:[si]
        inc si
        loop s1
    
        pop si
        pop bx
        pop ax
        ret
    
    
    show_str:
        push ax
        push dx
        push cx
        push si
        mov di,0
        mov bl,dh
        dec bl
        mov al,160
        mul bl
        mov bx,ax
        add dl,dl
        add bl,dl
        mov ax,0b800h
        mov es,ax
        mov al,cl
    s:
        mov ch,0
        mov cl,ds:[si]
        jcxz ok
        mov es:[bx+di],cl
        mov es:[bx+di+1],al
        add di,2
        inc si
        loop s
    ok:
        pop si
        pop cx
        pop dx
        pop ax
        ret
    code ends
    end start
    View Code
  • 相关阅读:
    CSS实现字母全大写
    人生职业规划与自身设想
    关于人生的一些想法,和淘客SEO的思想。
    保持积极向上的心态去把傻逼的坚持换成牛逼的结果
    SEO站群随想,及自我的认知和想法
    我是SEOer,我为自己代言
    打印出 html结构中的ul li
    js数据类型转换
    js object类型转换 内存泄漏 垃圾回收机制
    页面重置样式reset.css
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6929840.html
Copyright © 2011-2022 走看看