回 帖 发 新 帖 刷新版面

主题:菜鸟和我一起写程序

今天,我们来开始,写一个判断闰年的小程序,并且要有显示
好了 ,废话少说了,不然要扔白菜给我拉
 我们第一步是来思考,在DOS里面显示 input a year number 
 这个好解决  我们利用 21H的09号功能就可以显示拉
  第二步 我们来输入 数字,这个也不难,我们用21H的10号功能 对之进行写入数据
  第三步,我们把所输入的数字转换成实际大小的数字,把它存起来
  第四步,我们开始对这个数字进行运算,如果能整除四就显示是闰年,如果不是闰年的话就显示不是润年
   第五步,休息。。。。。~~。。~~~
data segment 
 infon db 'input a year number!$' ;$是表示显示结束的标识
 bushi db 'it is a leaf year!$'
 shi  db 'it is not a leaf year!$'
 w  dw 0  ;存放输入数字的变量
 buf db 8  ;输入数字的最大长度
    db ?   ;输入 数字的长度
    db 20 dup(?) ; 这个是用来存放我们输入数字的变量

data ends
stack segment 
   db dug 200(0)
stack ends
code segment
 assume cs:code,da:data,ss:stack
   start:mov ax,data
         mov ds,ax
         
       lea dx,infon
       mov ah,9
       int 21h ;这是显示输入数字的条件中断
 
       lea dx,buf
       mov ah,10    ;这是我们的功能号
       int 21h  ;这是我们要输入数字的条件中断
  (int 21h 是个什么意思,它的意思就是首先我们把下一个指令的CS 和IP压栈,然后去调用内存的0000:0021处的指令就此时的IP =000:21 CS=0000:23这里面装的就是命令的地址,当命令执行完了后,然后CS和IP的值恢复到从前,这是我个人的理解,)
      当我们输入指令完后,我们是不是有点眨眼乐
     我们输入的数据跑那里去了,我们怎么去找呢,这些数据存放的时候是以什么方式来存放的呢 
别 着急,我来告诉大家
数据是 存放 在  buf db 20 dug(?)里面的
但是这是我们要注意了,输入的每个数字都是以ASCII码存放的
那下一步就是把我们输入的数字给改成我们实际大小的数字
   下面 我们开始写子命令了,何谓子命令,就是在程序里面的程序
   那么我来开始call吧
  接着上面的继续写
 mov cl,[buf+1];这个是指向的存放数字位数地址里面的数据
 mov ch,0            当我们输入2008,那么CL=4
  call zhuan   ;调用我们的ZHUAN子程序,使我们得到实际大小的数字
  call  juge    ;调用我们的判断子程序
  
mov ax,4c00h
  int 21h      ;程序返回
    zhuan proc near   ;子程序的入口
  (当我们输入2004的时候,在其分配的内存一号是2 二号是0。。。。。,那么我们应该怎么进行转换呢,我们可以想要地址指向最后一个数字,然后在做一个乘法,向W里面进行加法运算,即可 ,从指向4开始,因为在分配空间里面大见为34H之减30H让它变成4
然后我们乘一个一,当到2时候,我们减30H后,再乘1000变2000然后向W里面进行加法运算就可以了,这就是我们的思路,想一想,你现在学到了什么没有!)
  mov si,buf+2 ;存放数据的第一地址
  add si,3     ;存放输入数据的最后的一个地址
 mov dh,30h ;;为什么不用AH因为我们要进行乘法运算要用到它
 mov bl,10   用来使AX的变1 100 1000的东西
 mov ax,1
(说到这里,我们想来谈一谈,关于在汇编里面的一些基本的乘法和除法运算,我们首先来看看,乘法,在8086里面,当乘数是8位时候,被乘数也必须是,8位,乘数是AL,被乘数是一个内存单元,或者也上一个寄存器,结果我们放到AX里面,当我们遇见16对16的时候,乘数即AX,其他的则是其他的字内存单远,或者是另一个寄存器
列如 10*1  我们可以mov al 1 mov bl,10 mul bl(byte ptr [?])结果放到AX里面
如果是10000*1时候,这里有个16位的 我们可是mov ax,1 mov bx,10000 mul bx这个时候结果,AX是低16位的数,DX是高16的数,当我们进行出发的时候,除数是8位的时候,被除数必须是16位置的,除数是16位的时候,被除数是32位置的 比如
1000/10 除数是10  很明显用16对8的搞,结果是AH存放余数,AL存放商,有时候会遇见溢出  如果是10000000/10 那么我们用ax,来存放低16位的数,DX用来存放高16位的数,结果是AX,存放商,DX存放余数表示方式 mov 1000,ax mov dx,2000 mov bx,10 div bx)
我们接着干什么呢。。。。。是不是有点头大了,没事,休息一下慢慢的看,[em1]
现在就是一个小小的循环了 我们来转换这几个数字吧!
ll:push ax
   sub byte ptr [si],dh ;注意什么是目的操作数,什么是源操作数
   mul byte ptr [si]    ;看,这里我们就要来用乘法拉改变其大小
   add w,ax             ;我们把乘的结果放到我们定义的内存空间里面
   dec si
   pop ax
   mul bl          ;ax变成了十了
  loop ll         ;当CX=0时,循环结束
ret              ;程序中断结束,程序返回
  zhuan endp    ;段结束
  jude proc near
   mov ax,w
   mov bl,4
   div bl  ;AL是商,AH是余数,如果AH=0那么不就是闰年拉
  cmp ah,0
  je ok1   ;AH是0就跳OK1
  jmp short ok2 ; 如果不是就条OK2
ok1:lea dx,shi
     mov ah,9
    int 21h
  ret 
ok2:lea dx,bushi
    mov ah,9
   int 21h
ret
jude endp
code ends
end start
好了,写完了,希望对大家有帮助 

[em3][em3]

回复列表 (共1个回复)

沙发

顶!!!!!!!!

我来回复

您尚未登录,请登录后再回复。点此登录或注册