數據處理的兩個基本問題

總結chapter5-8編程

這幾章分散引入或總結了很多零碎的知識點,包括尋址方式、新增指令用法、僞指令,等等。知識自己難度不大,可是,因爲比較零散,也容易給初學者形成困擾。所以,建議對內容進行分門別類梳理、概括、總結,藉助思惟導圖、表格等形式,讓知識結構化、體系化、清晰化。不只有助於本身學習理解,也有助於後期複習。數組

第五章[bx]和loop指令在上一篇博客有總結框架

第六章包含多個段的程序oop

assume cs:code
code segment

     dw    0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h

     mov bx,0
     mov ax,0

     mov cx,8
 s: add ax,cs:[bx]
     add bx,2
     loop s

     mov ax,4c00h
     int 21h
code ends
end
   

"dw"的含義是定義字型數據。學習

經過ds=0760,可知道程序從0770開始存放,因爲數據存放在代碼段中,程序運行的時候cs中存放代碼段的段地址,因此能夠從cs中獲得它們的段地址。編碼

用debug加載後,能夠將ip設置爲10h,從而使cs:ip指向程序中的第一條指令。再用t命令,p命令,或者是g命令執行。spa

 

assume cs:code
code segment

     dw    0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h

start :   mov bx,0
             mov ax,0

              mov cx,8
 s:          add ax,cs:[bx]
              add bx,2
              loop s

               mov ax,4c00h
               int 21h
  code ends
  end  start

加入標號start,而這個標號在僞代碼end的後面出現。end的做用除了通知編譯器程序結束外,還能夠通知編譯器程序的入口在什麼地方。咱們用end指令指明瞭程序的入口在標號start處。debug

咱們知道在單任務系統中,可執行文件中的程序執行過程以下:3d

1.由其餘的程序(debug\command或其餘程序)將可執行文件中的程序加載入內存。code

2.設置cs:ip指向程序的第一條要執行的指令(即程序的入口),從而使程序得以運行。

3.程序運行結束後,返回到加載者。有了這種方法,就能夠這樣來安排程序的框架:

assume cs:code

code segment

      :

      :

    數據

      :

      :

start:

       :

       :

      代碼

        :

         :

code ends

end start

下面的程序實現依次用內存0:0-0:f單元中的內容改寫程序中的數據,數據的傳送用棧來進行。棧空間設置在程序內。

assume cs:codesg
codesg segment

     dw    0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
     dw   0,0,0,0,0,0,0,0,0,0  ;10個字單元用做棧空間
start:      mov ax,cs
            mov ss,ax
            mov sp,30h  
            
            mov ax,0
            mov ds,ax
            
            mov bx,0
            mov cx,8
        s:  push [bx]
            pop cs:[bx]
            add bx,2
            loop s
                
            mov ax,4c00h
            int 21h
codesg ends
end

cs:10-cs:2f的內存空間看成棧來用,初始狀態下棧爲空,因此ss:sp要指向棧底,則設置ss:sp指向cs:30

預留16個字單元

dw 16 dup(0)

將數據、代碼、棧放入不一樣的段

assume cs:b,ds:a,ss:c1
a segment

     dw    0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
a ends

c1 segment
  dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
c1 ends

b segment

d:      mov ax,c1
            mov ss,ax
            mov sp,20h      ;但願用C1段看成棧空間,設置ss:sp指向c:20
            
            mov ax,a
            mov ds,ax       ;但願用ds:bx訪問a段中的數據,ds指向a段
            
            mov bx,0        ;ds:bx指向a段中的第一個單元
            mov cx,8
        s:  push [bx]
            add bx,2
            loop s          ;以上將a段中的0-15個單元中的8個字型數據依次入棧
            
            mov bx,0
            mov cx,8
        s0: pop [bx]
            add bx,2
            loop s0         ;以上依次出棧8個字型數據到a段的0-15個單元中
                
            mov ax,4c00h
            int 21h
b ends
end  d                      ;d處是要執行的第一條指令,即程序的入口

第七章 更靈活的定位內存地址的方法

and 和 or 指令 

and指令:邏輯與指令,按位進行與運算。

經過該指令可將操做對象的相應位設爲0,其餘位不變。

or指令: 邏輯或指令,按位進行或運算。

經過該指令可將操做對象的相應位設爲1,其餘位不變。

關於ascii碼

世界上有不少編碼方案,有一種方案叫作ascii碼,是在計算機系統中一般被採用的。簡單地說,所謂編碼方案,就是一套規則,它約定了用什麼樣的信息來表示現實對象。咱們能夠看到,顯卡在處理文本信息的時候,是按照ascii碼的規則進行的。這也就是說,若是咱們要想在顯示器上看到"a",就要給顯卡提供「a「的ascii碼,61h,如何提供?固然是寫入顯存中。

咱們能夠在彙編程序中,用'.....'的方式指明數據是以字符的形式給出的,編譯器將它們轉化爲相對應的ascii碼。

大小寫轉換

assume cs:codesg,ds:datasg
datasg segment
db 'BaSiC'
db 'iNfOMaTiOn'
datasg ends
codesg segment
 start: mov ax,datasg
        mov ds,ax       ;設置ds指向datasg段
        
        mov bx,0        ;設置(bx)=0,ds:bx指向'BaSiC'的第一個字母
        
        mov cx,5        ;設置循環次數5,由於'BaSiC'有5個字母
      s:mov al,[bx]     ;將ASCII碼從ds:bx所指的單元中取出
        and al,11011111B ;將al中的ASCII碼的第5位置爲0,變爲大寫字母
        mov [bx],al      ;將轉變後的ASCII碼寫會原單元
        inc bx           ;(bx)加1,ds:bx指向下一個字母
        loop s
        
        mov bx,5         ;設置(bx)=5,ds:bx指向'iNfOMaTiOn'的第一個字母
        mov cx,11        ;設置循環次數11,由於'iNfOMaTiOn'有11個字母
     s0:mov al,[bx]
        or al,00100000B    ;將al中的ASCII碼的第5個位置爲1,變爲小寫字母
        mov [bx],al
        inc bx
        loop s0
        
        mov ax,4c00h
        int 21h
        
codesg ends
end start

 

c語言: a[i],b[i]

彙編語言: 0[bx],5[bx]

經過比較咱們能夠發現,[bx+idata]的方式爲高級語言實現數組提供了便利機制。

si和di是8086CPU中和bx功能相近的寄存器,si和di不可以分紅兩個8位寄存器來使用。

assume cs:codesg,ds:datasg
datasg segment
  db 'welcome to masm!'
  db '................'
datasg ends
codesg segment
 start: mov ax,datasg
          mov ds,ax
          mov ds,ax
          mov si,0
          mov cx,8
       s: mov ax,0[si]
          mov 16[si],ax
          add si,2
          loop s
          
          mov ax,4c00h
          int 21h
codesg ends
end start
      

[bx+si+idata]表示一個內存單元,它的偏移地址爲(bx)+(si)+idata(即bx中的數值加上si中的數值再加上idata)

 

 第八章 數據處理的兩個基本問題

咱們定義的描述性符號:reg和sreg

reg的集合包括:ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di

sreg的集合包括: ds,ss,cs,es

在8086CPU中,只有這4個寄存器能夠用在」[...]「中來進行內存單元的尋址。好比下面的指令是正確的:

mov ax,[bx]

mov ax,[bx+si]

mov ax,[bx+bi]

mov ax,[bp]

mov ax,[bp+si]

mov ax,[bp+bi]

mov ax,[si]

mov ax,[di]

mov ax,[bx+si+idata]

mov ax,[bx+di+idata]

mov ax,[bp+si+idata]

mov ax,[bp+di+idata]

div指令

div指令時除法指令,使用div作除法的時候應注意如下問題。

1.除數:有8位和16位兩種,在一個reg或內存單元中。

2.被除數:默認放在AX或DX中,若是除數爲8位,被除數則爲16位,默認在AX中存放,若是除數爲16位,被除數則爲32位,在DX和AX中存放,DX存放高16位,AX存放低16位。

2.結果:若是除數爲8位,則AL存儲除法操做的商,AH存儲除法操做的餘數。若是除數爲16位,則AX存儲除法操做的商,DX存儲除法操做的餘數。

求10001/100

assume cs:code, ds:data
data segment
dd 100001
dw 100
data ends
code segment
start: mov dx,1
       mov ax,86A1h
       mov bx,64h
       div bx
       
       mov ax,4c00h
       int 21h
code ends
end start
       

商ax=03e8h,餘數dx=1

 

dup

dup是一個操做符,在彙編語言中db、dw、dd等同樣,也是由編譯器識別處理的符號。它是和db、dw、dd等數據定義僞指令配合使用的,用來進行數據的重複。

好比:db 2 dup (0)

定義了3個字節,它們的值都是0,至關於db 0,0,0

db 3 dup(0,1,2)

定義了9個字節,它們是0,1,2,0,1,2,0,1,2.至關於db 0,1,2,0,1,2,0,1,2

相關文章
相關標籤/搜索