講道理關於這道題,真的哎呀痛苦是一方面,其實真的不怎麼想寫,不過最後還是去把這個程式自己給除錯了一下題目如下所示
這裡其實就是需要注意的就是暫存器的保護,以及之前幾篇文章中講的函式的呼叫
assume cs:code
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
data ends
temp segment
db 10 dup(0)
temp ends
stack segment
db 64 dup(0)
stack ends
code segment
start:
mov ax,stack ;設定棧段
mov ss,ax
mov sp,64 ;設定sp
mov ax,data
mov es,ax ;設定es資料段
mov ax,temp ;設定data資料段
mov ds,ax ;設定資料段
mov si,0 ;設定暫存器的初始值
mov bp,0
mov bx,0
mov di,0
mov cx,21
s: push cx ;壓入cx
mov ax,es:[bx] ;給資料的1975,以0結束在write_str
mov ds:[si],ax ;ds是ax
mov ax,es:[bx+2] ;es為data段當中的
mov ds:[si+2],ax ;比如說第二個資料1976,39給的是ah,al給的是31
mov byte ptr ds:[si+4],0 ;第5個資料給0在write_str裡面使用
mov dh,24 ;
sub dh,cl ;
24-21從第三行開始
mov dl,3 ;從第三列開始
mov cl,2 ;給cl為2為綠色
call show_str ;呼叫show_str函式
push dx ;儲存每行每列
mov ax,es:[84+bp]
mov dx,es:[84+bp+2]
call dtoc
pop dx
add dl,10 ;從第三列開始往後加的列數,比如說1975如果這裡為4那麼下乙個資料會緊跟其後
call show_str
push dx ;儲存dx,因為dtoc子程式會用到dx
mov ax,es:[168+di] ;展示雇員數量
mov dx,0
call dtoc ;呼叫轉換的方法
pop dx ;
add dl,10
call show_str
push dx
push cx
mov ax,es:[84+bp]
mov dx,es:[84+bp+2]
mov cx,es:[168+di]
call divdw ;呼叫防止移除除法程式
call dtoc
pop cx
pop dx
add dl,10
call show_str
add bx,4 ;bx跨四個位元組的資料因為比如說1975就是四個位元組
add bp,4 ;收入就是四個位元組資料,所以加4
add di,2 ;雇員數
pop cx
loop s
mov ax,4c00h
int21h show_str:
push ax ;壓入ax
push bx ;壓入bx
push cx ;壓入cx
push si ;壓入si
push di ;因為之後都還要使用
push es
mov bl,cl ;給bl位2,也就是綠色
mov bh,0
mov ax,0b800h
mov es,ax
mov al,0a0h
mov ah,0
mul dh ;哪一行
mov di,ax
mov al,2h
mov ah,0
mul dl ;哪一列
add di,ax
write_str: ;寫入字元的函式
mov ch,0
mov cl,[si]
jcxz ok
mov es:[di],cl ;屬於哪個字元
mov es:[di+1],bl;綠色寫入進去
inc si
add di,2
jmp short write_str
ok:pop es ;出棧操作
pop di
pop si
pop cx
pop bx
pop ax
retdivdw:
push bx ;都要儲存這個bx,因為前面取1975那些資料的時候會用到
push ax ;ax先入棧,因為之後的結果會影響ax
mov ax,dx ;將dx先給cx,要先把高16位先做除法
mov dx,0 ;把dx置為0
div cx ;如果除數為16位,則被除數為32位,ax為商,dx為餘數
mov bx,ax ;將ax的值給bx
pop ax ;找回ax原先的值
div cx ;注意此時dx為餘數的值還沒變,這裡dx為5,所以就是0x54240/0x0a = 0x86a0
mov cx,dx ;儲存餘數到cx
mov dx,bx ;設定最高位為dx也就是第一次除法運算得到的ax
pop bx
ret
dtoc:
push bx
push cx
push si
mov cx,0
push cx
mov bx,1
div_continue: ;除法運算
mov cx,10 ;設定cx,作為除數
call divdw ;呼叫除法函式
add cx,30h ;加30
push cx ;將cx壓棧
inc bx ;算除法了幾次
mov cx,ax ;
jcxz jumpzero ;如果cx為0,就跳到jumpzero
jmp div_continue ;跳到div_continue
jumpzero:
mov cx,bx ;餘數個數
remainder_move:
pop bx ;儲存的算的餘數的值
mov ds:[si],bx ;賦值給ds:[si]
inc si
loop remainder_move
pop si
pop cx
pop bx
retcode ends
end start
程式執行結果 8086彙編顯示中文
具體請參考 github專案 先給個效果圖 給出模板程式如下,有詳細注釋 datas segment 字模資料,可用字模生成程式生成,替換掉此處即可,此處使用的是16 16的黑體字模,32byte 字 tw db 000h,00ch,04fh,08ch,06fh,0ach,028h,0ach,00a...
8086CPU彙編 顯示字串
在第8行第5列以紅色字型顯示 welcome to masm assume ds data,cs code data segment db welcome to masm 0 data ends code segment start mov ax,data mov ds,ax mov si,0 在8...
學習筆記 8086中的乘法和除法
乘法mul 要麼都是8位,要麼都是16位 8位情況下 預設運算元在al中,另外乙個運算元可以是暫存器,也可以是記憶體單元 結果儲存在ax中 16位情況下 預設運算元在ax中,結果高16位放在dx中,低16位放在ax中 除法div 要麼被除數是16位,除數是8位。要麼被除數是32位,除數是16位 除數...