編程:在屏幕中間分別顯示綠色、綠底紅色、白底藍色的字符串 'welcome to masm!'


; 編程:在屏幕中間分別顯示綠色、綠底紅色、白底藍色的字符串 'welcome to masm!'
assume cs:codesg , ds:datasg , ss:stacksg
datasg segment
        db 'welcome to masm!'                  ;要顯示字符串
        db 2h , 24h , 71h                            ;3行字符串分別的顯示效果
datasg ends
stacksg segment
        dw 0h,0h,0h,0h,0h,0h,0h,0h           ;其實2個字單元就可以搞定了,程序只用到了2個字單元;剛開始寫習慣性開辟16個字節剛好一行;這段空間是為了暫存一些子程序要重復用到的寄存器的值。
stacksg ends
codesg segment
start:  mov ax , datasg
        mov ds , ax

        mov ax , stacksg
        mov ss , ax
        mov sp , 16                                   ;設置棧頂偏移,指向空棧的下一位16

        mov ax , 0B872h   
                                              ;一頁25行,設置顯示的第一行的位置
                                              ;SA=0B800,EA=6E0H(12行的偏移,11*160(每行160個字節)=1760)+40H【偏移到中間,(160-16*2(一個字母還要在后面存貯一個顯示屬性,16*2算出顯示指定字符串要占用的字節,然后用一行總的字節數減去顯示占用的,剩下沒用過的空間除以二得出一行偏移多少可以在中間顯示字符串) )%2=64】
                                              ;SA+EA=0B8720H, cpu寄存器有限,為了節省寄存器,可以直接設置SA=0B87c,后面偏移在*16+EA(A0)結果都一樣
        mov cx , 3                ;要顯示3行,設置循環3次
        mov bx , 0               ;用來控制偏移,獲取顏色,第一次循環為0,后面獲取的是第一個顏色2h;第二次循環為1,獲取第二個顏色24h ...
s:      mov es , ax                   ;用附加段寄存器存貯設置的顯示緩沖區地址
        push ax                          ;進棧保存ax,也就是初始的顯示緩沖區地址
        push cx                        ;后面還用到循環,只能先進棧保存最外層循環
        mov si , 0                       ;偏移讀取字符
        mov di , 0                      ;偏移存貯讀取到底字符
        mov cx , 16                   ;循環16次讀取字符串
s0:   mov al , [si]                                        ;一個字符8位,用al暫存讀到的字符
        mov es:[di] , al                                  ;把讀到的數據存到顯示緩沖區
        inc si                                                  ;偏移讀取下一個字符
        add di , 2                                            ;存儲下一個讀到的字符,應為顯示緩沖區每個字符后面要存放顏色屬性,所以先空開來
        loop s0

        mov al , [bx+si]           ;獲取第一個顏色,第一次循環后si=16,剛好指向數據段的2h
        mov cx , 16
        mov di , 1                    ;偶數偏移存放的是字符,對應的基數單元存放顏色屬性,設置初試值1
s1:   mov es:[di] , al
        add di , 2
        loop s1                 ;循環結束,第一行字符串的顯示位置,顏色,內容設置完成

        pop cx                  ;取出最開始外層循環進行設置第二行
        pop ax                  ;取出初始顯示緩沖區地址放入ax
        add ax , 000ah     ;一行160字節=40H,ax*16+40得到下一行顯示起始的位置;節省寄存器,%16,當做SA
        inc bx                    ;bx+1,下次讀取第二個顏色
        loop s                    ;執行最外層循環,cx=cx-1=2
        mov ax , 4c00h
        int 21h
codesg ends
end start
   //最終結果
知識背景:
    80*25彩色字符模式顯示緩沖區結構,內存地址B8000H~BFFFFH,編程中要加上0在最開頭,不然就錯了。0B8000H~0BFFFFH;向這個地址空間寫入數據,寫入的內容將 立即出現在顯示器。
   顯示器可以顯示25行,每行80個字符(00 00),每個字符有256中屬性。(背景色、前景色、閃爍、高亮等組合信息)
   一個字符在顯示緩沖區要占兩個字節(00 00),分別存放字符ascii和屬性。一屏的內容在顯示緩沖區占4000個字節。
   顯示緩沖區分8頁,顯示第0頁的內容就是0B8000H~B8F9F

   在一頁顯示緩沖區中:  
偏移 000~09F 對應顯示器上的第1行(80個字符占160個字節)
偏移 0A0~13F 對應顯示器上的第2行(1*160=A0H)
偏移 140~1DF 對應顯示器上的第3行(2*160=140H)
題目要在屏幕中間,就應該在第12行顯示第一串字符,每行0~159個字符,11*160=1760(6E0H)剛好是第12行首地址;
F00~F9F 對應25行(24*160)
00~01 單元對應顯示器第1列
02~03 單元對應顯示器第2列
...
9E~9F 單元對應顯示器第80列(79*2=9EH)

eg:顯示器的第0行第0列顯示紅底綠色高亮閃爍字符串‘ABCDEF’
  //字符串一直在閃  

*用匯編語言編程中, 凡是4位16進制數據最高位為字母(ABCDEF),必須在前面加數字0,編譯器好識別是一個數。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM