王爽彙編實驗10解答

10.1 顯示字符串

; multi-segment executable file template.

data segment
    ; add your data here!
    db 'Welcome to masm!',0
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:
; set segment registers:
    mov ax,stack
    mov ss,ax
    mov sp,256     
    mov ax,data
    mov ds, ax     
    ; add your code here     
    mov si,0
    mov dh,8 ; line=8
    mov dl,3 ; column=3
    mov bl,2 ;color=g       
    call show_str
        
    ;end of your code  
    
    mov ax, 4c00h ; exit to operating system.
    int 21h         

;show string
;dh:line(0-24) dl:column(0,79),bl:color  ds:si string start addr
;es:bx->0b800:offset   

show_str:     
    ;save registers
    push ax
    push es             
    push bx
    push dx
    ;init es
    mov ax,0b800h
    mov es,ax
    ;calc display memory offset according to line and columm
    mov al,dh   
    mov cl,160
    mul cl; 160 bytes per line    
    mov dh,0
    add ax,dx  ;offset = 160*line + 2*column
    add ax,dx 
    mov bx,ax           
l:  
    ;string end?
    mov cl,[si]   
    mov ch,0
    jcxz ok   
    ;begin write 
    mov al,cl
    mov es:[bx],al
    ;write color   
    mov es:[bx+1],cl              
    ;update indexs
    inc bx
    inc bx
    inc si  
    jmp short l  

ok:   
    ;recover registers     
    pop dx
    pop bx
    pop es
    pop ax
    ret 
    
  
    
    
    
    
    
    
    
    
ends

end start ; set entry point and stop the assembler.

10.2 解決除法溢出問題

; multi-segment executable file template.

data segment
    ; add your data here!
    pkey db "press any key...$"
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:
; set segment registers:
    mov ax, data
    mov ds, ax    
    
    mov ax,stack
    mov ss,ax
    mov sp,256

    ; add your code here        
    
    mov ax,4240h
    mov dx,000fh
    mov cx, 0ah
    call divdw   
     
    mov ax, 4c00h ; exit to operating system.
    int 21h     
    
;被除數 dx:ax  除數 cx  商 dx:ax 餘數 cx 
divdw: 
   ;save 
   push bx                    
   push si
   
   ;calc dx/cx
   ;save ax->bx
   mov bx,ax 
   mov ax,dx
   mov dx,0
   div cx
   ;save 商->si    
   mov si,ax
   ;calc (餘數+低16位)除法
   mov ax,bx
   div cx
   ;         
   mov cx,dx
   mov dx,si    
   
   pop si
   pop bx
   
   ret                  

  
ends

end start ; set entry point and stop the assembler.

10.3 數值顯示

    這裏有個地方需要說明一下,就是計算的時候,先算出來的是數值的低位,而存儲的時候先存儲的必須是高位。這裏用壓棧出棧的方法巧妙地解決了這個問題。

data segment
    ; add your data here!
    dw 12366,456,23456   
    db 30 dup (0)                          
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:
; set segment registers:
    mov ax,stack
    mov ss,ax
    mov sp,256     
    mov ax,data
    mov ds, ax     
    ; add your code here    
    
    mov cx,3   
    mov di,0
    mov si,6            
      
l3:             
    mov dx,0 ; not supported 32 bit now.
    mov ax,[di]   
    call itoa       
       
    mov dh,8 ; line=8   
    mov ax,di 
    add dh,al
    mov dl,3 ; column=3
    mov bl,7 ;color=white/black    
    call show_str  
    
    ;update si
    add si,bp   
    add dh,1
     
    inc di  
    inc di
    loop l3    
    ;end of your code  
    
    mov ax, 4c00h ; exit to operating system.
    int 21h
    
    
;convert int to string
;ax: int   dx:0
;ds:si string begin add
;bp:strlen
itoa:            
     ;save 
    
     push bx   
     push cx
     push dx
     push di
            
     mov bp,0
     mov bx,10    
l1:
     div bx  
     inc bp
     mov cx,ax
     push dx 
     mov dx,0;clear 被除數的高16位    
     jcxz itoa_ok         
     jmp short l1
itoa_ok:     
     mov cx,bp ;strlen
     ;begin pop into ds:si
     mov di,si
l2:
     pop ax
     add ax,30h
     mov [di],al
     inc di    
     loop l2
     
     mov al,0
     mov [di],al          ;last 0 added    
     
     pop di
     pop dx
     pop cx
     pop bx
  
      
     ret                       
 
;show string
;dh:line(0-24) dl:column(0,79),bl:color  ds:si string start addr
;es:bx->0b800:offset   

show_str:     
    ;save registers      
    push cx
    push ax
    push es             
    push bx
    push dx      
    push bx  ;save color
  
    ;init es
    mov ax,0b800h
    mov es,ax
    ;calc display memory offset according to line and columm
    mov al,dh   
    mov cl,160
    mul cl; 160 bytes per line    
    mov dh,0
    add ax,dx  ;offset = 160*line + 2*column
    add ax,dx 
    mov bx,ax  
    
    pop ax          ;restore color
    mov ah,al           
l:  
    ;string end?
    mov cl,[si]   
    mov ch,0
    jcxz ok   
    ;begin write 
    mov al,cl
    mov es:[bx],al
    ;write color   
    mov es:[bx+1],ah            
    ;update indexs
    inc bx
    inc bx
    inc si  
    jmp short l  

ok:   
    ;recover registers     
    pop dx
    pop bx
    pop es
    pop ax        
    pop cx
    ret             
    
    
ends

end start ; set entry point and stop the assembler.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章