zoukankan      html  css  js  c++  java
  • 汇编代码

      1 assume cs:code , ds:data , ss:stack
      2 
      3 ; 数据段
      4 data segment
      5 
      6         db '1975','1976','1977','1978','1979','1980','1981','1982','1983'    ;第一个偏移值:0
      7 
      8         db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
      9 
     10         db '1993','1994','1995'        ;最后一个偏移值:53H(83D)
     11 
     12         ;以上是表示21年的21个字符串
     13 
     14  
     15 
     16         dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514        ;第一个偏移值:54H(84D)
     17 
     18         dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000        ;最后一个偏移值:A7H(167D)
     19 
     20         ;以上是表示21年公司总收入的21个dword型数据
     21 
     22  
     23 
     24         dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226        ;第一个偏移值是:A8H(168D)
     25 
     26         dw 11542,14430,15257,17800                                                    ;最后一个偏移值是:D2(210D)
     27 
     28         ;以上是表示21年公司雇员人数的21个word型数据
     29 
     30     dw 64 dup(?)        ; 因为最后转换成字符串的空间不够,所以需要再多申请这么多空间
     31 
     32 data ends
     33 
     34 
     35 
     36 ; 栈段
     37 stack segment
     38 
     39     db 256 dup (?)
     40 
     41 stack ends
     42 
     43 
     44 ; 计算后的数据存放段
     45 table segment
     46 
     47         db 21 dup ('year sunm ne ?? ')
     48 
     49     dw 32 dup(?)        ; 因为最后转换成字符串的空间不够,所以需要再多申请这么多空间
     50 
     51 table ends
     52 
     53 
     54 
     55 ; 代码段
     56 code segment
     57 
     58  start:
     59 
     60     ; 设置栈段地址
     61     mov ax , stack
     62     mov ss , ax
     63     mov sp , 256
     64 
     65 
     66 
     67     ; 计算数据段中的数据(计算人均收入,也就是收入除以雇员数)
     68     mov ax , data
     69     mov ds , ax
     70     mov bx , 0
     71     call Calculate
     72 
     73 
     74 
     75 
     76     ; 循环,将双字节的数据的整型数转换成字符型
     77     mov bx , 0
     78     mov si , 0            ; 设置字符串输出的首地址
     79     mov cx , 21            ; 设置循环次数
     80  again: 
     81     ; 复制年份到ds段
     82     mov ax , es:[ bx ]
     83     mov ds:[ si ] , ax
     84     mov ax , es:[ bx + 2 ]
     85     mov ds:[ si + 2 ] , ax
     86     mov word ptr ds:[ si + 4 ] , 0    ; 存入0,表示间隔
     87     add bx , 5            ; 因为只需跳过一个空格,空格占一个字节,再加上前面读取的4个字节
     88     add si , 6
     89 
     90 
     91     mov ax , es:[ bx ]        ; 获取公司总收入的dword型数据的低位
     92     mov dx , es:[ bx + 2 ];        ; 获取公司总收入的dword型数据的高位
     93     call dtoc            ; 调用子程序,将dword型数据转换成数字符串型,放到ds:si指定的位置
     94     add bx , 5            ; 跳过已经读取的字节再加上一个空格
     95     inc si                ; 如果去掉这个自增1,则存放他们之间的间隔0为一个字节,没有去掉这个自增就为一个字
     96 
     97     mov ax , es:[ bx ]        ; 获取公司雇员人数的word型数据
     98     mov dx , 0            ; 因为是word型数据,所以高位不需要,为0
     99     call dtoc            ; 调用子程序,将dword型数据转换成数字符串型,放到ds:si指定的位置
    100     add bx , 3            ; 跳过已经读取的字节再加上一个空格
    101     inc si                ; 如果去掉这个自增1,则存放他们之间的间隔0为一个字节,没有去掉这个自增就为一个字
    102 
    103     mov ax , es:[ bx ]        ; 获取公司雇员的人均收入
    104     mov dx , 0            ; 因为是word型数据,所以高位不需要,为0
    105     call dtoc            ; 调用子程序,将dword型数据转换成数字符串型,放到ds:si指定的位置
    106     add bx , 3            ; 跳过已经读取的字节再加上一个空格
    107     inc si                ; 如果去掉这个自增1,则存放他们之间的间隔0为一个字节,没有去掉这个自增就为一个字
    108 
    109   loop again
    110 
    111 
    112 
    113     ; 循环,用于显示所有的字符串
    114     mov dh , 0            ; 第0行
    115     mov dl , 2            ; 第2列
    116     mov si , 0            ; 设置指向字符串首地址偏移量
    117     mov cx , 22            ; 外循环共循环21次(因为第一次为了直接跳到循环处而一次性执行循环,所以需要多加一次循环)
    118 
    119     jmp show_start            ; 跳到开始出,以便能直接使用loop循环一次性输出
    120 
    121  show_again1:
    122 
    123     push cx                ; 现场保护
    124     mov cx , 4            ; 内循环共循环4次
    125 
    126    show_again2:
    127 
    128     push cx                ; 因为CX还要用来设置颜色,所以还要保护
    129     mov ch , 0
    130     mov cl , 01h            ; 设置颜色(蓝色)
    131     call show_str
    132     add si , 2            ; 加上间隔符,进行下一组字符串的输出
    133     add dl , 10            ; 每输出一串字符列就空开几列
    134     pop cx                ; 恢复内循环的循环次数值
    135 
    136    loop show_again2
    137 
    138     add dh , 1            ; 输出完一组就要换下一行
    139     mov dl , 2            ; 输出完一组列就要归位
    140     pop cx                ; 恢复外循环的循环次数值
    141 show_start:
    142  loop show_again1
    143 
    144 
    145 
    146     ; 结束程序
    147     mov ax , 4c00h
    148     int 21h
    149 
    150 
    151 
    152 ; 子程序
    153 ; 计算数据段中的数据(计算平均收入,也就是收入除以雇员数)
    154 ; 入口参数:ds:bx为待计算的数据段
    155 ; 出口参数:计算好后的数据将放在table数据段中,也可以用 es:0 来直接获取这个table数据段的首地址
    156 Calculate:
    157 
    158         mov ax , table
    159         mov es , ax            ;设置要写入数据的段寄存器
    160 
    161         mov bp , 0            ;设置table段的偏移地址
    162 
    163         mov di , 0            ;设置雇员数每次增加的值(因为与其他值相比只有雇员数是2字节,所以要做特殊处理)
    164 
    165         mov cx , 21            ;设置循环的值为21次
    166 
    167     again_1:
    168         
    169         mov ax , ds:[bx]        ;复制年份的低字
    170         mov es:[bp] , ax
    171 
    172         mov ax , ds:[bx + 2]        ;复制年份的高字
    173         mov es:[bp + 2] , ax
    174 
    175 
    176 
    177         mov ax , ds:0A8H.[di]        ;复制雇员数(十进制168)
    178 
    179         mov es:[bp + 0AH] , ax        ;加10是因为复制了2个字节,而且写入的时候要输入一个空格,
    180                                     ;并且这个位置是在复制了4个字节后的再加5个字节的位置
    181 
    182 
    183         mov ax , ds:54H.[bx]        ;复制收入的低字节(十进制84)
    184         mov es:[bp + 5] , ax
    185 
    186         mov dx , ds:54H.[bx + 2]    ;复制收入的高字节(十进制84)
    187         mov es:[bp + 7] , dx
    188 
    189 
    190 
    191         div word ptr ds:0A8H.[di]    ;因为除数是2个字节(16位)的,所以也用di(di每次循环增加2)
    192 
    193         mov es:[bp + 0DH] , ax        ;复制算好的人均收入
    194 
    195 
    196 
    197         add bp , 16        ;进行下一组写入
    198 
    199         add di , 2        ;用于计算雇员数的值加2,因为他一次值复制了2个字节
    200 
    201         add bx , 4        ;复制了一次后要加上4字节,以便下一次读出和计算
    202 
    203     loop again_1
    204 
    205   ret                    ; Calculate子程序返回
    206 
    207 
    208 
    209 
    210 ;参数: (ax) = dword型数据的低16位
    211 ;      (dx) = dword型数据的高16位
    212 ;      (cx) = 除数
    213 ;返回: (dx) = 结果的高16位
    214 ;      (ax) = 结果的低16位
    215 ;      (cx) = 余数
    216 divdw:  ;子程序定义开始
    217 
    218         push ax
    219 
    220         mov ax,dx
    221 
    222         mov dx,0
    223 
    224         div cx
    225 
    226         mov bx,ax
    227 
    228         pop ax
    229 
    230         div cx
    231 
    232         mov cx,dx
    233 
    234         mov dx,bx
    235 
    236         ret   ;子程序定义结束
    237 
    238 
    239 
    240 
    241 ; 功能:将dword型数据转变为表示十进制数的字符,字符以0为结尾符
    242 ; 参数:(ax) = dword型数据的低16位
    243 ;      (dx) = dword型数据的高16位
    244 ;      ds:si指向字符串的首地址
    245 ; 返回:无
    246   dtoc: push cx                ; 保护现场
    247     push bx                ; 保护现场
    248     push si                ; 保存用来输出结果的字符串的首地址
    249 
    250     mov byte ptr ds:[ si ] , 0    ;先写入结束符(写在首位,以便配合栈结构)
    251 
    252     inc si
    253 
    254     mov cx , 1
    255 
    256 again_3:mov cx , 10            ; 做除数,每次都除以10,以便得到余数,从而求出每个位的值
    257 
    258     call divdw            ; 调用除法子程序,因为这个除法子程序可以防止数据溢出
    259 
    260     add cl , 30H            ;加上30H成为字符的ASCII码
    261 
    262     mov ds:[ si ] , cl        ;存入到指定的数据段
    263 
    264 
    265     ; 判断商的低位和高位是否都为0如果都为0,则表示结束
    266     mov cx , 0
    267     or cx , ax
    268     or cx , dx
    269 
    270     jcxz ok1
    271 
    272     inc si
    273     inc cx                ;因为loop会将cx减少1,所以要先加1
    274 
    275     loop again_3
    276 
    277  ok1:   mov byte ptr ds:[ si + 1 ] , 0    ;尾部也写入结束符
    278 
    279     pop si                ; 取出用来输出结果的首地址
    280     mov bx , si            ; bx用来做最后的数据存入,所以也是为输出结果的首地址
    281 
    282     mov al , ds:[ si ]        ;从得到的第一个数据开始遍历
    283     mov ah , 0            ;只要低位,高位归零
    284 
    285     push ax                ;结束符先入栈
    286 
    287     ;把得出的字符倒过来,因为求余得到的数是倒着的
    288 again_4:inc si
    289 
    290     mov al , ds:[ si ]
    291     mov ah , 0            ;只要低位,高位归零
    292 
    293     mov cx , ax
    294 
    295     jcxz ok2            ;已经全部临时存入栈中
    296 
    297     push ax
    298 
    299     inc cx                ;因为loop会将cx减少1,所以要先加1
    300 
    301     loop again_4
    302 
    303   ok2:  pop cx                ;从栈中取出,正好实现倒叙
    304 
    305     mov ds:[ bx ] , cl        ;只要低位,高位归零
    306 
    307     jcxz return
    308 
    309     inc bx
    310     inc cx                ;因为loop会将cx减少1,所以要先加1
    311 
    312     loop ok2
    313 
    314 return: pop bx                ; 恢复现场
    315     pop cx                ; 恢复现场
    316     ret                ; 返回
    317 
    318 
    319 
    320 
    321 ;子程序
    322 ;功能:在指定的位置 , 用指定的颜色 , 显示一个用0结束的字符串
    323 ;参数:(dh) = 行号(取值范围0~24) , (dl) = 列号(取值范围0~79)
    324 ;     (cl) = 颜色 , ds:si指向字符串首地址
    325 show_str:
    326 
    327     push dx                ; 现场保护
    328 
    329     mov ax , 000ah            ;转换成行需要乘以a(10)
    330     mul dh                ;计算写入位置的行
    331     add ax , 0b800h            ;B800是起始位置,所以加上规定的行数
    332 
    333 
    334     add dl , dl            ;计算写入位置的列
    335     mov dh , 0
    336 
    337 
    338     mov es , ax            ;设置写入位置的寄存器
    339     mov di , dx
    340     
    341     mov al , cl            ;保存颜色
    342 
    343 
    344     mov cx , 2
    345     jmp first_start
    346    again_2:
    347 
    348     mov cl , ds:[si]        ;获取要显示的数据
    349     mov ch , 0            ;不需要高位
    350     jcxz ok                ;如果是0则返回(结束这个子程序)
    351     
    352     mov es:[di] , cl        ;将字符写入
    353     mov es:[di + 1] , al        ;写入颜色
    354     add di , 2            ;指向下一个要写入的位置
    355     inc si                ;指向下一个要读取字符的位置
    356     mov cl , 2            ;again循环每次都成立
    357 first_start:
    358    loop again_2
    359 ok:    pop dx                ; 恢复
    360     ret                ;返回(结束)这个子程序
    361 
    362 
    363 code ends
    364 
    365 
    366 end start
  • 相关阅读:
    错误:/usr/lib/python2.4/sitepackages/_sqlitecache.so: wrong ELF class: ELFCLASS32
    Ubuntu 12.04LTS g++编译错误解决
    yum Error: Cannot retrieve repository metadata (repomd.xml) for repository: xxxxx
    win7中制作ubuntu 1210启动盘
    Java 访问 Hbase 的API
    光标所能实现的不同形状
    Asp遍历服务器对象的代码
    一些好的网站
    通用高效分页存储过程代码
    一些模拟windows 界面的 js
  • 原文地址:https://www.cnblogs.com/Zblogs/p/3285753.html
Copyright © 2011-2022 走看看