汇编语言中的MVC

一 MVC指令

1.移动字符串指令MVC
移动字符串指令MVC的格式为:
MVC D1(L,B1),D2(B2) (移动字符串)
功能:(D1+(B1)) ← (D2+(B2))
L个字符
指令的执行用开始于D2(B2)的L字节替换开始于D1(B1)的L字节的内容。L个字节的内容
每次改变一个,从左边开始。如果域不重叠的话,这一事实是不重要的,但当域重叠时就特
别重要。本指令的操作码为D2。指令执行不改变条件代码CC。
例如指令:
MVC 14(8,R12),0(R1)
产生编码D207 C00E 1000。
SS语句可以使用隐式地址。这里,正如RS和SI指令中的情形一样,隐式地址中不说明
变址寄存器。当用一个隐式地址说明第一个操作数时,通过将其放在第一个操作数括号中说
明长度。这是一个可能产生混淆的地方。例如,指令:
MVC FIELD1(15),FIRLD2
说明操作数的长度为15,第一个操作数的地址为FIELD1,而不是R15内容的偏移。SS指令
中的长度说明允许为0,如果这样做了,生成的长度代码为0

二 汇编EXAMPLE


data segment
    org 80h
    psp     dw 0ffh dup(?)
    ddd     db 'diretory:$'
    head    db 'name           size      type      date       time    ',0dh,0ah,24h
    space   db '        ',24h
    dir     db 'xxx       <dir>   ',24h
    fn    db 200h dup(?)
    dta     db 128 dup(?)
    msg     db 'press any key to continue...',0dh,0ah,24h
    newline db 0dh,0ah,24h
    count   db ?
    show    db 0
    base_10     dw      10
    used_32bits_high    dw      0
    used_32bits_low     dw      0
    var_32bits_high     dw      0
    var_32bits_low     dw      0
    quotidient_32bits_high      dw      0
    quotidient_32bits_low       dw      0
    negate_mask         equ      0FFFFh
    lowest_signed_32bits_high        dw     8000h
    lowest_signed_32bits_low         dw     0000h
    lowest_signed_32bits_string      db     '-2147483648$'
    qhigh       dw      0
    rhigh       dw      0
    qlow        dw      0
    rlow        dw      0
    qhigh_redundant     dw      0
    rhigh_redundant     dw      0
    q_0         dw      0
    qhigh0      equ     0h
    rhigh0      equ     0h
    qhigh1      equ     1999h
    rhigh1      equ     6h
    qhigh2      equ     3333h
    rhigh2      equ     2h
    qhigh3      equ     4CCCh
    rhigh3      equ     8h
    qhigh4      equ     6666h
    rhigh4      equ     4h
    qhigh5      equ     8000h
    rhigh5      equ     0h
    qhigh6      equ     9999h
    rhigh6      equ     6h
    qhigh7      equ     0B333h
    rhigh7      equ     2h
    qhigh8      equ     0CCCCh
    rhigh8      equ     8h
    qhigh9      equ     0E666h
    rhigh9      equ     4h
    filenum     db      0
    dirnum      db      0
    filespace   db      ' File(s)    $'
    dirspace    db      ' Dir(s)     $'
    bytes       db      ' Bytes.',0dh,0ah,24h
    bytesfree   db      ' Bytes free.',0dh,0ah,24h
data ends

stack1  segment   stack
       dw  0ffh  dup(0)
stack1  ends

main    segment
        assume cs:main,ds:data,ss:stack1
        org 100h
cmdln equ byte ptr es:[82h] ;command line data

;-------------------------------------------------------------------------------
p1      proc near
        push ds
        mov ax,data
        mov ds,ax
        pop psp
        mov es,psp
        mov ax,stack1
        mov ss,ax
        mov cl,byte ptr es:[80h]
        cmp cl,0               ;command line?
        jne l4                 ;yes
no_dir:
        mov ah,19h             ;no
        int 21h
        add al,'a'
        mov byte ptr[fn],al
        mov word ptr[fn+1],5c3ah
        mov ah,47h             ;current directory but no driver,so have to
        lea si,fn[3]           ;use 19h to add myself
        sub al,'a'
        mov dl,al
        int 21h

        lea di,fn[3]      ;to point di to the end of the diretory

l7:
        mov al,[di]
        cmp al,0
        je l6
        inc di
        jmp l7

l4:
        lea si,cmdln              
        lea di,fn
        cld
        xor ch,ch
        dec cl
        ;rep movsb

        lea di,fn
        lea bx,cmdln
        lea bp,fn

repeat:

        mov al,es:[bx]
        mov ds:[bp],al
        inc bx
        inc bp
        inc di
        dec cl
        jnz repeat

l6:
        mov cl,[di-1]                ;end by '\' ?
        cmp cl,92                   ;92-->'\'
        je l8                        ;yes
        ;mov byte ptr[di],92         ;no
        ;inc di

        cmp byte ptr[di-1],'W'
        jne notW
        mov al,1
        mov [show],al
notW:
        cmp byte ptr[di-1],92           ;'\'
        je l8
        dec di
        jz no_dir
        jmp notW

l8:
        mov word ptr[di],0a0dh       ;end by $ for printing
        mov byte ptr[di+2],24h
        mov ah,09h                   ;print "directory:*:\*\*\"
        ;lea dx,ddd
        mov dx,offset ddd
        int 21h
        mov ah,09h
        lea dx,fn
        int 21h
        mov ah,09h
        mov al,[show]
        cmp al,1
        je  w_head
        lea dx,head
        int 21h
w_head:
        

        mov word ptr[di],2e2ah        ;add '*.* ' at the end
        mov word ptr[di+2],002ah

l5:
        lea dx,dta
        mov ah,1ah
        int 21h
        mov ah,4eh                   ;first fdt matched
        mov cx,16h                   ;all file
        lea dx,fn
        int 21h
        
        call outp              ;print first file imformation
        mov cl,1
        mov count,cl
        ;-------------
        ;mov ah,4ch
        ;int 21h 
        ;-----------
l2:
        mov ah,4fh                   ;next fdt
        int 21h
        jc l0                        ;end when no file any more

        call outp              ;print next file imformation
        mov cl,count
        inc cl
        mov count,cl

        cmp cl,14h
        ja pause
pause_end:
        jmp l2

pause:
        mov dl,[show]
        cmp dl,1
        je pause_end
        mov   ah,9h;move 9 into ah (9 is the interrupt for output)
        lea   dx,msg;move the message into dx
        int   21h  ;call dos function
        mov   ah,7h;move 7 into ah (7 is the interrupt for input)
        mov   dx,00h;get the actual input
        int   21h  ;dos interrupt
        mov cl,0
        mov count,cl
        jmp pause_end

l0:     ;int 20h                       ;end
        mov dl,[show]
        cmp dl,0
        je not_newline

        mov ah,2                     ;new line
        mov dl,0dh
        int 21h
        mov ah,2
        mov dl,0ah
        int 21h

not_newline:
        lea dx,[space]
        mov ah,09h
        int 21h
        mov al,[filenum]
        xor ah,ah
        mov [var_32bits_low],ax
        xor al,al
        mov [var_32bits_high],ax
        call showspace

        lea dx,filespace
        mov ah,09h
        int 21h

        mov ax,[used_32bits_high]
        mov [var_32bits_high],ax
        mov ax,[used_32bits_low]
        mov [var_32bits_low],ax
        call showspace
        lea dx,bytes
        mov ah,09h
        int 21h


        lea dx,[space]
        mov ah,09h
        int 21h

        mov al,[dirnum]
        xor ah,ah
        mov [var_32bits_low],ax
        xor al,al
        mov [var_32bits_high],ax
        call showspace

        lea dx,[dirspace]
        mov ah,09h
        int 21h
        ;-----------------------get free space
        mov dl,fn[0]

        sub dl,'a'
        mov ah,36h
        int 21h

        mul bx
        mov bx,cx
        xor cx,cx

        call mymul32

        mov var_32bits_high,cx
        mov [var_32bits_low],bx
        call showspace

        lea dx,bytesfree
        mov ah,09h
        int 21h

        mov ah,4ch
        int 21h


p1      endp

pspace proc near
        push dx
        push ax
        mov dl, ' '
        mov ah, 2h
        int 21h
        pop ax
        pop dx
pspace endp

printax proc near
        cmp ax,0
        je pret
        push bx
        push cx
        push ax
        push dx

        xor cx,cx
        ;jmp lable1
b11:    xor dx,dx
lable1: mov si,10
        div si

        push dx
        inc cx
        cmp ax,0
        jne b11

b22:     pop dx
        add dl,30h
        mov ah,2
        int 21h
        loop b22

        pop dx
        pop ax
        pop cx
        pop bx
pret:        ret
printax endp

printax_hex proc near
        mov cx,4        ; print 4 hex digits (= 16 bits)
.print_digit:
        rol ax,4   ; move the currently left-most digit into the least significant 4 bits
        mov dl,al
        and dl,0Fh  ; isolate the hex digit we want to print
        add dl,'0'  ; and convert it into a character..
        cmp dl,'9'  ; ...
        jbe .ok     ; ...
        add dl,7    ; ... (for 'A'..'F')
.ok:            ; ...
        push ax    ; save EAX on the stack temporarily
        mov ah,2    ; INT 21H / AH=2: write character to stdout
        int 21h
        pop ax     ; restore EAX
        loop .print_digit
        ret
printax_hex endp

;----------------------------print the file imfomation--------------------
outp    proc near
        push bx
        push dx
        push ax
        push cx
        mov cx,16
        lea bx,dta[1eh]       ;print name
o0:
        mov dl,[bx]
        cmp dl,0
        je o1
        mov ah,2
        int 21h
        dec cx
        inc bx
        jmp o0


o1:
        mov ah,02h            ;print space between name and size
        mov dl,20h
        int 21h
        loop o1
        call b2d              ;print size and dir type
        ;----judge is W
        mov dl,[show]
        cmp dl,1
        je w_file
        call datm             ;print date and time


        mov ah,2                     ;new line
        mov dl,0dh
        int 21h
        mov ah,2
        mov dl,0ah
        int 21h
w_file:
        pop cx
        pop ax
        pop dx
        pop bx
        ret
outp    endp
;------------------------------print size-------------------------------------
b2d     proc near
        push cx
        push ax
        push dx
        push si


        xor cx,cx
        lea si,dta[1ah]
        mov ax,[si]
        call add_used_space
        call add_filenum
        cmp ax,0
        je b4
        ;----judge is W
        mov dl,[show]
        cmp dl,1
        je b5
        xor cx,cx
b1:
        xor dx,dx
        mov si,10
        div si

        push dx
        inc cx
        cmp ax,0
        jne b1
        mov si,cx

b2:
        pop dx
        add dl,30h
        mov ah,2
        int 21h
        loop b2

        mov cx,10
        sub cx,si
b3:
        mov ah,02h
        mov dl,20h
        int 21h
        loop b3

        ;----judge is W
        mov dl,[show]
        cmp dl,1
        je b5

        mov ah,9
        lea dx,space
        int 21h
        jmp b5

b4:
        call add_dirnum
        call sub_filenum
        ;----judge is W
        mov dl,[show]
        cmp dl,1
        je b5
        mov ah,09h
        lea dx,dir
        int 21h

b5:
        pop si
        pop dx
        pop ax
        pop cx
    ret
b2d     endp

add_filenum proc near
        push ax
        mov al,[filenum]
        inc al
        mov [filenum],al
        pop ax
        ret
add_filenum endp

add_dirnum proc near
        push ax
        mov al,[dirnum]
        inc al
        mov [dirnum],al
        pop ax
        ret
add_dirnum endp

sub_filenum proc near
        push ax
        mov al,[filenum]
        dec al
        mov [filenum],al
        pop ax
        ret
sub_filenum endp

;------------------------------print date and time-----------------------------------------------
datm    proc near
        push ax
        push bx
        push cx
        push dx
        push di


        lea bx,dta[18h];data
        mov di,[bx]
        mov cx,7;year
        xor bx,bx
d1:
        shl di,1
        rcl bx,1
        loop d1
        add bx,1980
        call bi2de
        mov ah,2
        mov dl,"."
        int 21h

        mov cx,4;month
        xor bx,bx
d2:
        shl di,1
        rcl bx,1
        loop d2
        call bi2de
        mov ah,2
        mov dl,"."
        int 21h

        mov cx,5;day
        xor bx,bx
d3:
        shl di,1
        rcl bx,1
        loop d3
        call bi2de
        mov cx,3
d7:
        mov ah,2
        mov dl," "
        int 21h
        loop d7

;time
        lea bx,dta[16h]
        mov di,[bx]
        mov cx,5;hour
        xor bx,bx
d5:
        shl di,1
        rcl bx,1
        loop d5
        call bi2de
        mov ah,2
        mov dl,":"
        int 21h
        mov cx,6;min
        xor bx,bx
d6:
        shl di,1
        rcl bx,1
        loop d6
        call bi2de


    pop di
    pop dx
    pop cx
    pop bx
    pop ax
    ret
datm    endp

;---------------------------------binary2decimal-----------------------------
bi2de    proc near
        push ax

        cmp bx,9
        ja bi0
        mov ah,2
        mov dl,'0'
        int 21h
bi0:
        xor cx,cx
        mov ax,bx
bi1:
        xor dx,dx
        mov si,10
        div si

        push dx
        inc cx
        cmp ax,0
        jne bi1

bi2:
        pop dx
        add dl,30h
        mov ah,2
        int 21h
        loop bi2

        pop ax
        ret
bi2de    endp

;----------------multiplies dx:ax x cx:bx return dx:ax:cx:bx
mymul32    proc     near

         push si
         push di
         mov      si,dx       ;save op1hi in si
         mov      di,ax       ;save op1lo in di
         mul      bx          ;op1l0 x op2lo
         push     ax          ;save 1st (32 bit) pp. on stack
         push     dx
;
         mov      ax,si       ;op1hi in ax
         mul      bx          ;op1hi x op2l0
         pop      bx          ;add 2nd (48 bit) pp. to pp1
         add      ax,bx
         adc      dx,0
         push     ax
         mov      bx,dx       ;pp1 + pp2 in bx:tos:tos+2
;
         mov      ax,di       ;op1lo in ax
         mul      cx          ;op1lo x op2hi
         pop      di          ;add 3rd (48 bit) pp. to pp1 + pp2
         add      di,ax
         push     di
         mov      di,0
         adc      bx,dx
         adc      di,0        ;pp1+pp2+pp3 in di:bx:tos:tos+2
;
         mov      ax,si       ;op1hi in ax
         mul      cx          ;op1hi x op2hi
         add      ax,bx       ;add 4th (64 bit) pp. to pp1+pp2+pp3
         adc      dx,di
         pop      cx
         pop      bx          ;final product in dx:ax:cx:bx
;
         pop      di
         pop      si
         ret
mymul32    endp

showspace proc near
    push ax
    push bx
    push dx
    push cx
    mov     ax,0
    mov     bx,0        ;bx: quotidient_32bits_high
    mov     dx,0        ;dx: quotidient_32bits_low
    mov     cx,0        ;counter = 0
;16bits or 32bits ?
    mov     ax,var_32bits_high
    cmp     ax,0
    jne     _32bits_routine
    jmp     _16bits_routine

;;;
_32bits_routine:
    mov     cx,0
;if == -2147483648 (-2^31)
    mov     ax,var_32bits_high
    cmp     ax,lowest_signed_32bits_high
    jne     check_if_neg
    mov     ax,var_32bits_low
    cmp     ax,lowest_signed_32bits_low
    jne     check_if_neg
;then
    lea     dx,lowest_signed_32bits_string
    mov     ah,9
    int     21h
    jmp     return_to_dos
;if < 0
check_if_neg:
    mov     ax,var_32bits_high
    cmp     ax,0
    jnl      preparations
;then print "-" ...
    mov     ah,2
    mov     dl,'-'
    int     21h
;... and negate number
    ;---------xor 0ffffffff , + 1----------
    mov     ax,var_32bits_high
    xor     ax,negate_mask
    mov     var_32bits_high,ax
    mov     ax,var_32bits_low
    xor     ax,negate_mask
    inc     ax
    mov     var_32bits_low,ax
    jnc     preparations
    mov     ax,var_32bits_high
    inc     ax
    mov     var_32bits_high,ax
preparations:
    mov     ax,var_32bits_high
    mov     quotidient_32bits_high,ax
    mov     ax,var_32bits_low
    mov     quotidient_32bits_low,ax
while_32bits:
; while >0 do
    mov     ax,quotidient_32bits_high
    cmp     ax,0
    jne     div_high_part
    mov     ax,quotidient_32bits_low
    cmp     ax,0
    jne     div_high_part
    jmp     print_char
div_high_part:
;divide high part
    mov     dx,0
    mov     ax,quotidient_32bits_high
    div     base_10
    mov     qhigh,ax
    mov     rhigh,dx
;case rhigh
    mov     ax,rhigh
    cmp     ax,0
    je      _rhigh0
    cmp     ax,1
    je      _rhigh1
    cmp     ax,2
    je      _rhigh2
    cmp     ax,3
    je      _rhigh3
    cmp     ax,4
    je      _rhigh4
    cmp     ax,5
    je      _rhigh5
    cmp     ax,6
    je      _rhigh6
    cmp     ax,7
    je      _rhigh7
    cmp     ax,8
    je      __rhigh8
    cmp     ax,9
    je      __rhigh9
_rhigh0:
    mov     ax,qhigh0
    mov     qhigh_redundant,ax
    mov     ax,rhigh0
    mov     rhigh_redundant,ax
    jmp     _aftercase

_rhigh1:
    mov     ax,qhigh1
    mov     qhigh_redundant,ax
    mov     ax,rhigh1
    mov     rhigh_redundant,ax
    jmp     _aftercase
__rhigh8:
    jmp _rhigh8
__rhigh9:
    jmp _rhigh9
_rhigh2:
    mov     ax,qhigh2
    mov     qhigh_redundant,ax
    mov     ax,rhigh2
    mov     rhigh_redundant,ax
    jmp     _aftercase
_rhigh3:
    mov     ax,qhigh3
    mov     qhigh_redundant,ax
    mov     ax,rhigh3
    mov     rhigh_redundant,ax
    jmp     _aftercase
_rhigh4:
    mov     ax,qhigh4
    mov     qhigh_redundant,ax
    mov     ax,rhigh4
    mov     rhigh_redundant,ax
    jmp     _aftercase
_rhigh5:
    mov     ax,qhigh5
    mov     qhigh_redundant,ax
    mov     ax,rhigh5
    mov     rhigh_redundant,ax
    jmp     _aftercase
_rhigh6:
    mov     ax,qhigh6
    mov     qhigh_redundant,ax
    mov     ax,rhigh6
    mov     rhigh_redundant,ax
    jmp     _aftercase
_rhigh7:
    mov     ax,qhigh7
    mov     qhigh_redundant,ax
    mov     ax,rhigh7
    mov     rhigh_redundant,ax
    jmp     _aftercase
_rhigh8:
    mov     ax,qhigh8
    mov     qhigh_redundant,ax
    mov     ax,rhigh8
    mov     rhigh_redundant,ax
    jmp     _aftercase
_rhigh9:
    mov     ax,qhigh9
    mov     qhigh_redundant,ax
    mov     ax,rhigh9
    mov     rhigh_redundant,ax
    jmp     _aftercase
_aftercase:
;divide low part
    mov     ax,0
    mov     q_0,ax
    mov     dx,0
    mov     ax,quotidient_32bits_low
    div     base_10
    mov     qlow,ax
    mov     rlow,dx
    mov     ax,rlow
    add     ax,rhigh_redundant
;if remainder >= 10
    cmp     ax,base_10
    jl      after_if
    sub     ax,base_10
    mov     dx,1
    mov     q_0,dx
after_if:
    mov     rlow,ax
    mov     ax,q_0
    add     ax,qlow
    mov     qlow,ax
    jnc     label1
    mov     ax,qhigh
    inc     ax
    mov     qhigh,ax
label1:
    mov     ax,qlow
    add     ax,qhigh_redundant
    mov     qlow,ax
    jnc     label2
    mov     ax,qhigh
    inc     ax
    mov     qhigh,ax
label2:
;push remainder to stack
    mov     ax,rlow
    push    ax
    inc     cx
    mov     ax,qhigh
    mov     quotidient_32bits_high,ax
    mov     ax,qlow
    mov     quotidient_32bits_low,ax
    jmp     while_32bits

;;;
_16bits_routine:
    mov     ax,var_32bits_low
    mov     bx,0   ;bx: quotient
    mov     cx,0
while_loop:
    cmp     ax,0
    je      print_char
    mov     dx,0
    div     base_10
    mov     bx,ax ;ax stores quotidient
    mov     ax,dx ;dx stores remainder
;push remainder
    push    ax
;counter = counter + 1
    inc     cx
;numerator = quotidient
    mov     ax,bx
    jmp     while_loop
print_char:
    cmp     cx,0
    je      return_to_dos
    pop     ax
;because at this point 0 <= ax <= 9, setting ah = 2 does not change the results
    mov     ah,2
    mov     dl,al
    add     dl,30h   ;0-> '0',1->'1',....
    int     21h
    dec     cx
    jmp     print_char

return_to_dos:

    pop cx
    pop dx
    pop bx
    pop ax
    ret
showspace endp

;--------input:ax----------
add_used_space proc near
        push ax
        push bx
        push cx
        push dx

        mov dx,[used_32bits_low]
        add dx,ax
        jnc add_finish
        mov bx,[used_32bits_high]
        inc bx
        mov [used_32bits_high],bx

add_finish:
        mov [used_32bits_low],dx

        pop dx
        pop cx
        pop bx
        pop ax
        ret
add_used_space endp

main    ends
        end p1
  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值