小试汇编

来源:互联网 发布:淘宝怎么上传 编辑:程序博客网 时间:2024/05/24 06:36

坤哥的作业~

-----------------

;date   : 2014-05-19;author : d4shman@gmail.com;lang: assembly实验一 循环程序的调试与运行一.实验目的掌握循环程序的调试运行方法二.实验内容1、程序1;数据段data segment  d1 db 2, -1,-3,5,6,9,18,-29,-72,8,122,-31,95,76,91,-2 ;db 表示其后面的数据类型是字节型(共16个)  rs db ?data ends;堆栈段stack1 segment  ; dup: 重复定义圆括号中指定的初值,次数有前面的数值决定,这里是100次  ; ?  : 只分配存储空间,不指定初值  db 100 dup(?) stack1 ends;代码段code segment  ;汇编中,far和near是子程序调用时的参数  ;如果子程序和调用程序在一个段中,子程序参数设为near, 否则为far  ;这里设为far是因为系统把主程序当做DOS调用的子程序,而它们不在同一个段中  main proc far    ;                     assume : 段寄存器关联说明伪指令    ;cs:code ,ds:data ,ss:stack1 : 代码段寄存器cs与code关联;数据段寄存器ds与data关联;堆栈段寄存器ss与stack1关联。    assume cs:code,ds:data,ss:stack1  ;定义程序入口  start:  push ds        ;将数据段寄存器ds压入栈中          sub ax,ax ;将ax寄存器清零(其他方法还有:1.MOV AX,0 2.AND AX,0 3.XOR AX,AX)          push ax ;ax寄存器入栈          mov ax,data    ;把data中的数据先暂存到ax          mov ds,ax      ;再经ax转存到ds寄存器(经过这两步是因为assume伪指令只是“关联”,而不是“赋值”)          lea bx,d1 ;把d1中的数据存放到寄存器bx中          mov cx,16 ;寄存器cx存的值置为16          mov dl,0       ;寄存器dl存的值置为0  lop1:   mov al,[bx]    ;把寄存器bx中的值存到al中          cmp al,0       ;比较寄存器al中的值与0的大小          jge jus        ;如果al中的值大于等于0,则跳转到jus          inc dl         ;否则,寄存器dl中的值加1  jus:    inc bx    ;寄存器bx中的值加1          dec cx         ;寄存器cx中的值减1          jnz lop1       ;如果cx中的值不为0就转移到循环体lop1          mov rs,dl      ;把dl中的值存入rs          add dl,30h     ;dl中存的值加30h          mov ah,2       ;ah中存的值为2          int 21h        ;int 21h是汇编中的中断指令,把控制权交给DOS          ret ;返回  main endpcode ends  ;程序结束标志  end startcomment* ///////////////   +总结+   ///////////////////上面的汇编代码实现了下面的C程序(统计数组中负数的个数):   int a[16] = {2, -1,-3,5,6,9,18,-29,-72,8,122,-31,95,76,91,-2};   int d = 0;   int c = 16;   while(c) {if(a[i] >= 0) {; //do nothing}else {d++;}c--;    }return d;///////////////  ---------  ///////////////////*    2.程序2data segment    num dw 6789h ;定义变量num为双字节(dw: double word)类型,值为6789hdata endsstack1 segment    db 100 dup(?)stack1 endscode segment     main proc far          assume cs:code,ds:data,ss:stack1     start:push ds           sub ax,ax           push ax           mov ax,data             mov ds,ax    ;以上和程序1都一样           mov bx,num   ;把num的值存到ds中           mov ch,4     ;ch中的值为4     rota:mov cl,4      ;cl中的值为4          rol bx,cl     ;把bx里的高4位移动到了低4位,比如1010 1111 0110 0000 变为 1111 0000 0110 1010          mov al,bl     ;把bx中低位地址(bl: b low)中的值存到al, 即0110 1010          and al,0fh    ;把0110 1010和0000 1111进行and操作,只保留了后4bit          add al,30h    ;把al中的值加30h          cmp al,3ah    ;比较al中的值和十进制数9的大小          jl print      ;当比al中的值小于3ah时,转移到print函数          add al,07h    ;否则(A-F),把al中的值加07h(ASCII码中9和A之间差了7个数)     print:mov dl,al    ;把al中的值存到dl中           mov ah,2                int 21h      ;产生中断时,ah中存的值为2,代表2号功能--字符输出,并且要输出的字符是dl中存放的数据           dec ch       ;ch中的值减1           jnz rota     ;当ch中的值不为0时,转移到rota           ret       main endp    code ends         end start comment* ///////////////  +总结+   ///////////////////上面的汇编代码实现了16进制转成2进制的功能。REFERENCE:    1)、http://222.240.219.68:8080/files/files_upload/content/material_161/COLUMN_4/default.htm2)、http://www.qi9.cn/html/785_443_8.html///////////////  --------  /////////////////// * 实验二 PC串行接口实验一.实验目的掌握PC机的基本串行通信二.实验内容参考程序data segment        flag db 0  ;定义变量flag,类型为字节,值为0        info db 13,10 ;13是回车,10是换行(见ASCII码表)                db 'please select(s=sending or r=receiving)'                db '$' ;'$'表示已经到了字符串尾                sendinfo db 13,10                         db 'sending...'                         db 13,10                         db '$'                receiveinfo db 13,10                          db 'receiving...'                          db 13,10                          db '$'data endsstack segment para stack 'stack'        ;如果没有最后的那个 'stack' 说明项,就需要自己设置 ss:sp         db 256 dup(0);初始化256字节空间,用0填充stack endscode segment        start proc far                assume cs:code,ds:data  ;因为上面的'stack',所以这里不必设置了                push ds;ds入栈                mov ax,0;ax清零                push ax;ax入栈                mov ax,data                mov ds,ax;data中的数据存入ds                mov al,0h;al清零                out 21h,al;将置0后的数据从21H号端口输出                mov dx,2fbh;dx中的值为2fbh                mov al,80h;al中的值为80h                out dx,al;将al中的数据从2fbh号端口输出  (下面在重复,不谈)                mov dx,2f8h                mov al,060h                out dx,al                mov dx,2f9h                mov al,0                out dx,al                mov dx,2fbh                mov al,0ah                out dx,al                mov dx,2fch                mov al,0ah                out dx,al                mov dx,2fch                mov al,0bh                out dx,al                mov dx,2f9h                mov al,01h                out dx,al                sti;cli是关中断,防止有些硬件中断对程序的干扰,sti是开中断,允许硬件中断                ;                push ds                mov dx,offset irecve;把irecve在段里的偏移地址赋给dx                mov ax,seg irecve;seg是伪操作符,用来取后面符号irecve的段地址                mov ds,ax                mov al,0bh                mov ah,25h                int 21h;调用DOS的第25h号功能                pop ds                mov dx,offset info                mov ah,9                int 21h;调用DOS的第09h号功能                mov ah,1                int 21h;调用DOS的第01h号功能                cmp al,'s';比较al中的值和字符's'                je sending;如果相同,则转移到sending                cmp al,'s'                je sending                cmp al,'s';比较al中的值和字符's'                jne next;当它们不同时,转移到next        sending:                call send;调用send函数                ret        next:   cmp al,'r';比较al中的值和字符‘r’                je receiving;如果相同,则转移到receiving                cmp al,'r';再比较                jne quit;如果不同,就转移到quit        receiving:                call receive;调用receive函数        quit:   ret        start endp;实现消息接收功能receive proc;proc是定义子程序的伪指令,它和endp分别表示子程序定义的开始和结束两者必须成对出现        mov dx,offset receiveinfo;上面出现过,把receiveinfo在段里的偏移地址赋给dx        mov ah,9        int 21h;9号系统调用refore:        cmp flag,'!';比较flag和字符'!'        jz sequit;如果相同,则转移到sequit        jmp reforerequit:retreceive endp;子程序结束;实现消息发送功能send proc;又是一个子程序        mov dx, offset sendinfo;(这里和上面receive子程序一样,不谈)        mov ah,9        int 21hsefore: cmp flag,'!'jz sequit;如果flag是!,则转移到sequitmov dx,2fdhin al,dx;从2fdh端口读入8位,放在al寄存器中test al,20h;test: 两操作数作与运算,仅修改标志位,不回送结果jz sefore;test结果为零,则转移到seforemov ah,0int 16h;Keyboard Service,等待键盘输入mov flag,almov dx,2f8hout dx,al;将置al中的数据从2f8h号端口输出mov bx,0mov ah,14int 10h;在当前光标处显示字符, REFERENCE:http://www.itzhai.com/assembly-int-10h-description.htmljmp seforesequit:retsend endp;子程序结束irecve proc;子程序之3        push ax        push bx        push dx        push ds        mov dx,2fdh        in al ,dx        test al,1eh        jnz error;测试结果不为0时转移到error        mov dx,2f8h        in al,dx        mov flag,al        and al,7fh        mov bx,0        mov ah,14        int 10h        jmp exiterror:        mov dx,2f8h        in al,dx;从2f8h端口读入8位,放在al寄存器中        mov al,'?'        mov bx,0        mov ah,14        int 10hexit:        mov al,20h        out 20h,al        pop ds;ds出栈        pop dx        pop bx        pop ax        sti        iret;从中断中返回irecve endp;子程序结束code ends        end startcomment* ///////////////  +总结+   ///////////////////上面的汇编代码实现了消息的发送和接受的功能///////////////  --------  /////////////////// *


0 0
原创粉丝点击