1. 程式人生 > >組合語言(第三版)實驗10-1,2

組合語言(第三版)實驗10-1,2

1.顯示字串 子程式描述: 名稱:show_str 功能:在指定的位置,用指定的顏色,顯示一個用0結束的字串。 引數:(dh)=行號(取值範圍0~24),(dl)=列號(取值範圍0~79), (cl)=顏色,ds:si指向字串的首地址 返回:無 應用舉例:在螢幕的8行3列,用綠色顯示data段中的字串。

程式碼:

assume cs:codesg
datasg segment
db 'welcome to masm!',0
datasg ends
codesg segment
    start:
    mov dh,8
    mov dl,3
    mov cl,2
    mov ax,data
    mov ds,ax
    mov si,0
call show_str mov ax,4c00h int 21h show_str: push dx push cx push ds push si ;棧儲存原資料 mov ax,0b800h mov es,ax ;視訊記憶體段地址 mov ax,0a0h mul dh mov bx,ax ;bx 行號(從0開始) mov ax,2 mul dl mov di,ax ;di 列號(從0開始) mov al,cl ;al 顏色 mov ch,0 set: mov cl,[si];cl 字串中的位元組 jcxz ok ;cx 為0
轉結束子程式 mov es:[bx+di],cl ;列中低位代表字元 mov es:[bx+di+1],al ;列中高位代表顏色 inc si add di,2 jmp short set ok: pop si pop ds pop cx pop dx ret codesg ends end start

2.解決除法溢位的問題 子程式描述 名稱:divdw 功能:進行不會產生溢位的除法運算,被除數為dword型,除數為word型,結果為dword型。 引數:(ax)=dword型資料的低16位 (dx)=dword型資料的高16位 (cx)=除數 返回:(dx)=結果的高16位,(ax)=結果的低16位 (cx)=餘數 應用舉例:計算1000000/10(F4240H/0AH) mov ax,4240h mov v dx,000fh mov cx,0ah call divdw

提示 給出一個公式: X:被除數,範圍:[0,FFFF FFFF] N:除數,範圍:[0,FFFF] H:X高16位,範圍:[0,FFFF] L:X低16位,範圍:[0,FFFF] int():描述性運算子,取商,比如:rem(38/10)=8 rem():描述性運算子,取餘數,比如:rem(38/10)=8 公式:X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N 這個公式將可能產生溢位的除法運算:X/N,轉變為多個不會產生溢位的除法運算。 公式中,等號右邊的所有除法運算都可以用div指令來做,肯定不會導致除法溢位。

解析: 根據公式: 1.int(H/N)*10000h即是將(高位/除數)所得商左移16位變為高位 2.rem(H/N)*10000H+L即是求第一步剩下的餘數

舉個例子(雖然例子中的數不會溢位): 在十進位制中328/2,被除數328的高位H為3,低位L為28,則根據 1.求得int(H/N)=int(3/2)=商1,餘1即rem(H/N),此時328/2的餘數為128 2.第一步得出的餘數為128,即128=1*100+28(rem(H/N)*100+L) 3.最後結果為328/2=164=1*100+128/2=int(H/N)*100+(rem(H/N)*100+L)/N

程式碼:

assume cs:codesg
datasg segment
    db 8 dup(0)
datasg ends
codesg segment
    start:
    mov ax,4240h
    mov dx,000fh
    mov cx,0ah
    call divdw
    mov ax,4c00h
    int 21h

    divdw:
    push ax               ;將ax存放至棧中,以便後面程式使用
    mov ax,dx             ;將ax設為H
    mov dx,0              ;將dx置零
    div cx                ;求得ax=int(H/N),dx=rem(H/N)
    mov bx,ax             ;bx即為最終輸出中高位儲存的數  
    pop ax                ;ax=L,dx=rem(H/N)
    div cx                ;相當於[dx*10000h+ax]/N
                          ;ax即為最終輸出中低位儲存的數
                          ;dx即為最終輸出中儲存的餘數
    mov cx,dx
    mov dx,bx             ;返回結果
    ret
codesg ends
end start