zoukankan      html  css  js  c++  java
  • 汇编学习笔记(8)子程序

    说的多不如做的多,子程序的功能十分重要,这篇笔记用来记录书上练习题的代码,加强对子程序的应用。

    在屏幕上指定位置显示字符串

    在转移指令那一章有个联系是要求在屏幕中间显示不同颜色的字体,当时我写的代码是这样

     1 assume cs:codesg,ds:data
     2 
     3 data segment
     4 db 'welcome to masm!'
     5 data ends
     6 
     7 codesg segment
     8     
     9 start:  mov ax,data
    10         mov ds,ax
    11         mov bx,0
    12         mov ax,0B800h
    13         mov es,ax
    14 
    15         ;第10行中间显示绿色字体
    16         mov si,10*160+32
    17         mov cx,16
    18     s:  mov al,ds:[bx]
    19         mov es:[si+24],al
    20         mov byte ptr es:[si+25],02h
    21         inc bx
    22         inc si
    23         inc si
    24         loop s
    25 
    26         ;第11行中间显示红底绿色字体
    27         mov si,11*160+32
    28         mov bx,0
    29         mov cx,16
    30     s1: mov al,ds:[bx]
    31         mov es:[si+24],al
    32         mov byte ptr es:[si+25],42h
    33         inc bx
    34         inc si
    35         inc si
    36         loop s1
    37 
    38         ;第12行中间显示白底蓝色字体
    39         mov si,12*160+32
    40         mov bx,0
    41         mov cx,16
    42     s2: mov al,ds:[bx]
    43         mov es:[si+24],al
    44         mov byte ptr es:[si+25],71h
    45         inc bx
    46         inc si
    47         inc si
    48         loop s2
    49 
    50         mov ax,4c00h
    51         int 21h
    52  
    53 codesg ends
    54 end start

    在学习了子程序之后可以更简洁的代码实现该功能

     1 assume cs:codesg,ds:data
     2 
     3 
     4 data segment
     5 db 'welcome to masm!',0
     6 data ends
     7 
     8 codesg segment
     9     
    10 start:  mov ax,data
    11         mov ds,ax
    12         mov ax,0B800h
    13         mov es,ax
    14         ;第10行中间显示绿色字体
    15         mov dh,10D
    16         mov dl,32D
    17         mov bl,02h
    18         call print
    19         ;第11行中间显示红底绿色字体
    20         mov dh,11D
    21         mov dl,32D
    22         mov bl,42h
    23         call print
    24         ;第12行中间显示白底蓝色字体
    25         mov dh,12D
    26         mov dl,32D
    27         mov bl,71h
    28         call print
    29 
    30         mov ax,4c00h
    31         int 21h
    32 
    33 print:  push ax
    34         push dx
    35         push bx
    36         mov al,160D
    37         mul dh      
    38         mov cl,dl
    39         mov ch,0
    40         add ax,cx  ;得到开始写入字符串的内存地址
    41         mov si,ax
    42         mov di,0
    43     s:  mov cl,ds:[di]
    44         mov ch,0
    45         jcxz s1
    46         mov es:[si],cl
    47         mov byte ptr es:[si+1],bl
    48         inc di
    49         inc si
    50         inc si
    51         loop s
    52     s1: pop bx
    53         pop ax
    54         pop dx
    55         ret
    56  
    57 codesg ends
    58 end start

    数值转换

     1 assume cs:codesg,ds:data
     2 
     3 
     4 data segment
     5 db 10 dup(0)
     6 data ends
     7 
     8 codesg segment
     9     
    10 start:  mov ax,data
    11         mov ds,ax
    12         mov si,0
    13         mov ax,1266d
    14         call doc
    15 
    16         ;第10行中间显示绿色字体
    17         mov dh,10D
    18         mov dl,32D
    19         mov bl,02h
    20         call print
    21         
    22 
    23         mov ax,4c00h
    24         int 21h
    25 
    26   doc:  push ax
    27         push si
    28     s0: mov bl,10d
    29         div bl
    30         add ah,30h
    31         mov ds:[si],ah
    32         mov ah,0
    33         inc si
    34         mov cl,al
    35         mov ch,0
    36         jcxz s2
    37         jmp short s0
    38 
    39     s2: mov byte ptr ds:[si],0
    40         pop si
    41         pop ax
    42         ret
    43 
    44 
    45 print:  push ax
    46         push dx
    47         push bx
    48         mov ax,0B800h
    49         mov es,ax
    50         mov al,160D
    51         mul dh      
    52         mov cl,dl
    53         mov ch,0
    54         add ax,cx  ;得到开始写入字符串的内存地址
    55         mov si,ax
    56         mov di,0
    57     s:  mov cl,ds:[di]
    58         mov ch,0
    59         jcxz s1
    60         mov es:[si],cl
    61         mov byte ptr es:[si+1],bl
    62         inc di
    63         inc si
    64         inc si
    65         loop s
    66     s1: pop bx
    67         pop ax
    68         pop dx
    69         ret
    70  
    71 codesg ends
    72 end start

    课程设计1

      1 assume cs:codesg,es:data,ss:stack
      2 data segment
      3 ;年份
      4 db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
      5 db '1984','1985','1986','1987','1988','1989','1900','1991','1992'
      6 db '1993','1994','1995'
      7 ;公司总收入
      8 dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
      9 dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
     10 ;雇员
     11 dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
     12 dw 11542,14430,45257,17800
     13 data ends
     14 
     15 ;栈空间
     16 stack segment 
     17 db 16 dup(0)
     18 stack ends
     19 
     20 ;临时内存空间,将字符串后面加0
     21 temp segment
     22 db 8 dup(0)
     23 temp ends
     24 
     25 codesg segment
     26     
     27 start:  ;清除屏幕上的原有内容
     28         mov ax,0b800h
     29         mov es,ax
     30         mov si,0
     31         mov cx,25*80
     32     x:  mov byte ptr es:[si],' '
     33         mov byte ptr es:[si+1],0
     34         inc si
     35         inc si
     36         loop x
     37         ;分配栈空间
     38         mov ax,stack
     39         mov ss,ax
     40         mov sp,16
     41         ;指定数据入口
     42         mov ax,data
     43         mov es,ax
     44         mov ax,temp
     45         mov ds,ax
     46         mov si,0
     47         mov di,0
     48         mov bx,0
     49         mov dh,4
     50         ;循环21次,输出21年数据
     51         mov cx,21
     52 
     53     x1: push cx
     54         ;显示年份
     55         mov ax,es:[di]
     56         mov ds:[si],ax
     57         mov ax,es:[di+2]
     58         mov ds:[si+2],ax
     59         mov byte ptr ds:[si+4],0
     60         mov dl,10
     61         mov cl,02h
     62         call print 
     63 
     64         ;显示公司收入
     65         mov ax,es:[di+84]
     66         push dx
     67         mov dx,es:[di+84+2]
     68         call dword_str
     69         pop dx
     70         mov dl,20h
     71         call print
     72 
     73         ;显示雇员人数
     74         mov ax,es:[bx+84+84]
     75         call word_str
     76         mov dl,40h
     77         call print
     78 
     79         ;计算人均收入并显示
     80         mov ax,es:[di+84]
     81         push dx
     82         mov dx,es:[di+84+2]
     83         div word ptr es:[bx+84+84]
     84         call word_str
     85         pop dx
     86         mov dl,60h
     87         call print
     88         add di,4
     89         add bx,2
     90         inc dh
     91         pop cx
     92         loop x1
     93         
     94         mov ax,4c00h
     95         int 21h
     96 
     97 
     98 
     99 
    100             ;显示ds:[si]开始的字符串
    101 print:      push es
    102             push ax
    103             push dx
    104             push bx
    105             push si
    106             push di
    107             push cx
    108             
    109             mov ax,0B800h
    110             mov es,ax
    111             mov al,160D
    112             mul dh      
    113             mov bl,dl
    114             mov bh,0
    115             add ax,bx  ;得到开始写入字符串的内存地址
    116             mov di,ax
    117             mov si,0
    118             mov ah,cl
    119 print_s:    mov cl,ds:[si]
    120             mov ch,0
    121             jcxz print_s1
    122             mov es:[di],cl
    123             mov byte ptr es:[di+1],ah
    124             inc si
    125             inc di
    126             inc di
    127             loop print_s
    128 print_s1:   pop cx
    129             pop di
    130             pop si
    131             pop bx
    132             pop dx
    133             pop ax
    134             pop es
    135             ret
    136 
    137             ;不会溢出的除法,参考公式X/N = int(H/N)*65536 + [rem(H/N)*65536 + L]/N
    138             ;65536=2^16=10000h
    139             ;(dx)被除数高16位 (ax)被除数低16位,(cx)除数
    140             ;返回(dx)商高16位 (ax)商低16位 (cx)余数
    141     divdw:  push bx
    142             push ax ;将被除数低16位入栈
    143             mov ax,dx
    144             mov dx,0
    145             div cx ;处理被除数的高16位,商放在ax中,余数放在dx中
    146             mov bx,ax;bx存储高16位的商,作为最终结果的高16位int(H/N)*65536
    147             pop ax ;低16位出栈,这是(dx)=被除数高16位的余数即上面公式的rem(H/N)*65536
    148             div cx ;处理低16位,[rem(H/N)*65536 + L]/N,余数放在dx中
    149             mov cx,dx
    150             mov dx,bx
    151             pop bx
    152             ret
    153 
    154             ;dword型数据转化为字符串,ds:[si]
    155             ;(dx)高16位,(ax)低16位
    156 dword_str:  push bx
    157             push cx
    158             push dx
    159             push ax
    160             push si
    161             mov bx,0
    162 
    163 dword_str_x:mov cx,10;cx存储除数
    164             call divdw
    165             push cx;将余数入栈,若不用栈操作则显示时是相反的顺序
    166             inc bx
    167             mov cx,dx
    168             jcxz dword_str_a;如果商的高16位等于0则验证低16位是否等于0
    169             jmp near ptr dword_str_x
    170 dword_str_a:mov cx,ax
    171             jcxz dword_str_x1;如果商的低16位也等于0则退出循环
    172             jmp near ptr dword_str_x
    173 
    174              
    175 dword_str_x1:mov cx,bx;循环次数
    176 dword_str_x2:pop ds:[si]
    177              add byte ptr ds:[si],30h;将数字+30h变成相应的字符串
    178              inc si
    179              loop dword_str_x2
    180 
    181              pop si
    182              pop ax
    183              pop dx
    184              pop cx
    185              pop bx
    186              ret
    187 
    188             ;word型数据转化为字符串
    189 word_str:   push bx
    190             push cx
    191             push dx
    192             push ax
    193             push si
    194             mov bx,0
    195 word_str_s: mov dx,0;防止溢出用16位除法
    196             mov cx,10
    197             div cx
    198             push dx
    199             inc bx
    200             mov cx,ax
    201             jcxz word_str_x
    202             jmp short word_str_s
    203 
    204 word_str_x: mov cx,bx
    205 word_str_x1:pop ds:[si]
    206             add byte ptr ds:[si],30h;将数字+30h变成相应的字符串
    207             inc si
    208             loop word_str_x1
    209 
    210             pop si
    211             pop ax
    212             pop dx
    213             pop cx
    214             pop bx
    215             ret
    216 
    217 
    218 codesg ends
    219 
    220 end start
    View Code

  • 相关阅读:
    Sql Server textcopy 的使用
    看来,我还是不适合犯罪
    Oracle 游标范例
    嵌入式学习方法 关于ARM+linux(转)
    存储控制器与外设之间的关系 (SDRAM与BANK6连接概述)
    socket和多线程可移植性编程基础(转)
    Linux设备驱动开发环境的搭建(转)
    Android JNI知识简介
    Linux USB驱动框架分析
    LINUX系统中动态链接库的创建和使用
  • 原文地址:https://www.cnblogs.com/michaelle/p/4023322.html
Copyright © 2011-2022 走看看