0
点赞
收藏
分享

微信扫一扫

第二个程序:判断闰年


data segment    ; 定义数据段
    infon db 0dh,0ah,'Please input a year: $'
    Y db 0dh,0ah,'This is a leap year! $'
    N db 0dh,0ah,'This is not a leap year! $'
    w dw 0			; the value of user input
    buf db 8		; the max capicity of buffer 
        db ?		; 预留一个字节的空间,值未知	record the length of user input
        db 8 dup(?)	; 预留八个字节的空间,值未知	record the string of user input
data ends

stack segment stack
    db 200 dup(0)
stack ends

code segment
   assume ds:data,ss:stack,cs:code
    start:mov ax,data
          mov ds,ax
          
          lea dx,infon
          mov ah,9
          int 21h 		 ; 在屏幕上显示提示信息

          lea dx,buf
          mov ah,10
          int 21h  		  ; 从键盘输入年份字符串
          
          mov cl, [buf+1]
          lea di,buf+2		; the first byte of input year string
          call datacate
          call ifyears
          jc a1
          
		 ; no
          lea dx,n
          mov ah,9
          int 21h
          jmp exit
		 
		; yes
    a1:   lea dx,y
          mov ah,9
          int 21h
		  
		; exit
    exit: mov ah,4ch
          int 21h
       
 

 datacate proc near				; put the value user input to w word byte unit
          push cx;       		; mov cl, [buf+1]                                                
          dec cx				; 'the length of input year' - 1
          lea si,buf+2
     tt1: inc si
          loop tt1				; the last byte of input year
          ;lea si,cx[di]
          pop cx			
     
      
          mov dh,30h
          mov bl,10
          mov ax,1
      l1: push ax					; no value change in loop, this is not necessary ?		no, the mul instruction will change ax
          sub  byte ptr  [si],dh	; get the value of input
          mul  byte ptr [si]
          add w,ax					; add value to w word byte
          pop ax					; return ax's value to last ax's last value 
          mul bl					; turn ax's value to 10 * ax's value
          dec si
          loop l1
          ret
 datacate endp


ifyears proc near
	   push  bx
	   push  cx
	   push  dx
	   mov ax,w			; get the year which is user input
	   mov cx,ax		
	   mov  dx,0
	   mov  bx,4
	   div  bx			; 
	   cmp  dx,0		; dx's value is the remainder of 'divide' result
	   jnz  lab1		; jump if not equal
	   
	   
						;------------------ the year could be completely divided by 4
	   mov  ax,cx
	   mov  bx,100
	   div  bx
	   cmp dx,0
	   jnz  lab2		
	   
	   
	   
						;----------------- the year could be completely divided by 100		   
	   mov  ax,cx
	   mov bx,400
	   div  bx
	   cmp  dx,0
	   jz  lab2

	   
						;----------------- the year couldn't be completely divided by 400
	   jmp lab1		  							
	   
 lab1: clc				; clear carry flag
	   jmp lab3
	   
 lab2: stc				; set carry flag
 
 lab3: pop  dx
	   pop  cx
	   pop  bx
	   ret
ifyears endp
code ends

end start
      
; 这是我的第一个较为完整的汇编程序,做了两个多小时.....	 --2014.07.22



db 指令相关, 来源于网上

; 1. 	-------------------------	db 指令
; DB 是Define Byte的简写,就是定义一个字节的意思。
; “假设OP1,OP2是已经用DB定义的变量”也就是说定义两个字节变量,变量名为OP1和OP2。
; dataseg     segment
; aa          db      ?
; bb          db      ?
; cc          db      ?
; dataseg     ends
; 
; 上面的DB又是什么意思?问号呢? 
; 定义的数据段,段名为dataseg,在该代码段中有三个字节变量,名称分别是aa,bb,cc,而且每个变量都没有赋值。也就是空的。; ?的意思就是说定义的变量所在的内存单元没有赋值,预留一个内存单元的空间。
	  
	  
	  

; 2.	  -------------------------		db 指令
; DB定义的,是一个字节类型的指针,完全没有容量的概念, 不存在容量的限制,没有存不下的问题。
; 数据存储从指针所指向的地址开始往下分配,需要填多少数据都可以。(当然还有一个段的大小不能超过64KB的限制)

; 你的困惑,是你强行将高级语言中一个变量只能存一个数据、是一个数据容器的概念直接拿来套用造成的。这样的概念对于汇编语言来说是错误的。

; 如果你这样定义:
; XY   DB  05H, 43H, 21H, 32H
; 那么,内存中数据就这么分布  
; 地址        数据
; XY+0       05
; XY+1       43
; XY+2       21
; XY+3       32

; 如果你改成这样定义:
; XZ  DW   4305H, 3221H
; 那么,内存中数据这么分布:
; XZ+0       05
; XZ+1       43
; XZ+2       21
; XZ+3       32

; 可以看出,这两种定义方式,数据在内存的分布是一模一样的。
; 区别仅仅是变量名的数据类型的属性不同。

; 如果你程序中这样用数据:
; MOV  AL, XY
; MOV  AH, XY+1
; 结果AX的内容变成4305H

; 与用指令 MOV  AX,  XZ 的结果也是一模一样。

; ===========
; 对你问题的补充的回复:
; ===========
; 在汇编语言中,并不需要为每个数据存储单元定义一个名字。
; 数据是可以直接按地址访问的。
; 实际上,经汇编程序翻译以后,和变量名就变成了直接按地址访问。
; 机器指令也只能按地址访问。
; 按地址访问数据时,需要明确数据类型。

; 定义一个名字,用名字代表具体的地址值(同时也隐含着数据类型), 是为了让汇编程序在汇编时,将指令中的变量名替换为地址,减少编程者的人工工作量,便于编写程序。	  
	  
	  
	  
	  
; 3.	-------------------------	proc  指令
; PROC在汇编中是过程定义伪指令的意思
; 关于汇编中proc near与proc far的用法

; 如果你的子程序和主程序在同一个代码段,则使用near,调用发生后,主程序堆栈中只压入ip值;
; 如果你的子程序和主程序不在一个代码段,则使用far,调用发生后,主程序堆栈中将压入cs、ip值;




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

# add at 2015.12.14


效果截图

第二个程序:判断闰年_变量名



举报

相关推荐

0 条评论