1. 程式人生 > >組合語言學習

組合語言學習

以下程式碼為自己實現,未拿書本做任何的參考,思路有不對或者不到位的地方歡迎大家指出,由於是新人,程式碼註解難免繁雜,望見諒!

assume ds : datasg, cs : codesg, ss : stacksg
;show_ptr : 接受引數,在指定行,指定列顯示指定的顏色
;dh : 行
;dl : 列
;cl : 顏色
;2017/8/27
datasg segment
db 'Welcome to masm!', 0
datasg ends


stacksg segment
dw 0, 0, 0, 0, 0, 0, 0, 0
stacksg ends


codesg segment
start :
mov ax, datasg
mov ds, ax


mov ax, stacksg
mov ss, ax
mov sp, 10h


mov dh, 8   ;傳遞引數,行,0~24
mov dl, 64    ;傳遞引數,列,0~79
mov cl, 2    ;顯示的顏色,黑底綠字


mov bx, 0
mov si, 0
mov di, 0

call show_str     ;將mov ax, 4c00h的ip入棧


mov ax, 4c00h
int 21h


show_str :
mov bx, 0B800H  ;視訊記憶體地址
mov es, bx


mov ax, 0           ;內容清零mov al, 0A0H   ;存放基地址,做八位乘法,八位暫存器乘法乘數預設放在al中
mul dh                 ;乘法結果儲存在ax中,ax的結果用來定位顯示在第幾行
mov dh, 0           ;高八位清零,dx = 0003
add ax, dx         ;定位要顯示的字串首字母地址,行+列,dx暫存器可以釋放
mov bx, ax

s0 : 
mov ch, 0
push cx                ;cl為要顯示的顏色
mov cl, ds : [si]
mov ch, 0
jcxz ok               ;判斷字串是否結束



;mov es : [ax + di], cl     ;放入視訊記憶體,字元ASCII碼放在低位位元組
mov es : [bx + di], cl
pop cx             ;顏色出棧,push和pop只能是16位暫存器
                        ;為什麼不是存放顏色屬性的cl入棧???因為push和pop指令只能按字單元形式訪堆疊
;mov es : [ax + di + 1], cl    ;錯誤,[bx + di(si) + idata],不要想當然
mov es : [bx + di + 1], cl     ;將顯示的顏色屬性放入視訊記憶體,字元顏色屬性放在高位位元組
inc si
add di, 2


jmp short s0   ;代替loop迴圈,因前面已經有結束迴圈的判斷


ok : 
ret    ;ip出棧


codesg ends
end start




assume ds : datasg, cs : codesg, ss : stacksg

;show_ptr : 接受引數,在指定行,指定列顯示指定的顏色
;dh : 行
;dl : 列
;cl : 顏色
;2017/8/27
datasg segment
db 'Welcome to masm!', 0
datasg ends


stacksg segment
dw 0, 0, 0, 0, 0, 0, 0, 0
stacksg ends


codesg segment
start :
mov ax, datasg
mov ds, ax


mov ax, stacksg
mov ss, ax
mov sp, 10h


mov dh, 8   ;傳遞引數,行,0~24
mov dl, 64    ;傳遞引數,列,0~79
mov cl, 2    ;顯示的顏色,黑底綠字


mov bx, 0
mov si, 0
mov di, 0

call show_str     


mov ax, 4c00h
int 21h


show_str :
mov bx, 0B800H  ;視訊記憶體地址
mov es, bx


mov ax, 0           ;內容清零mov al, 0A0H   ;存放基地址,做八位乘法,八位暫存器乘法乘數預設放在al中
mul dh                 ;乘法結果儲存在ax中,ax的結果用來定位顯示在第幾行
mov dh, 0           ;高八位清零,dx = 0003
add ax, dx         ;定位要顯示的字串首字母地址,行+列,dx暫存器可以釋放
mov bx, ax

s0 : 
mov ch, 0
push cx                ;cl為要顯示的顏色
mov cl, ds : [si]
mov ch, 0
jcxz ok               ;判斷字串是否結束



;mov es : [ax + di], cl     ;放入視訊記憶體,字元ASCII碼放在低位位元組
mov es : [bx + di], cl
pop cx             ;顏色出棧,push和pop只能是16位暫存器
                        ;為什麼不是存放顏色屬性的cl入棧???因為push和pop指令只能按字單元形式訪堆疊
;mov es : [ax + di + 1], cl    ;錯誤,[bx + di(si) + idata],不要想當然
mov es : [bx + di + 1], cl     ;將顯示的顏色屬性放入視訊記憶體,字元顏色屬性放在高位位元組
inc si
add di, 2


jmp short s0   


ok : 
ret    


codesg ends

end start

以上程式碼有以下幾點可以總結:

1.mul指令的運用,八位暫存器做乘法,結果存放在ax中,其中一個乘數預設放在al(底八位暫存器),另一個乘數可以放在八位暫存器或者記憶體單元,需要注意的是八位暫存器也可以是高八位的暫存器,比如dh.

舉例如下:

mov al, 10

mov dh, 15

mul dh

經過除錯發現是沒有提示錯誤的

2.push和pop指令

兩個指令只能以字單元形式(兩個位元組)形式訪問棧,因此上面程式碼雖然顏色屬性放在cl中,但仍然要轉換為16位再入棧,出棧亦如此,程式碼剛開始實現時候是寫了push cl,和pop cl,後來發現一直儲存,所以改為push cx和pop cx

3.[bx + si(di) + idata]的格式

要嚴格按照格式,其中的bx不能換做其他暫存器,剛開始用的ax暫存器發現報錯,另外格式si(di)和idata的順序也不能調換,調換也會報錯



相關推薦

組合語言學習:使用masm32尋找1-100中的質數

最近有點自閉,事情賊多,還要學這麼變態的彙編(╥╯^╰╥)。經過異常艱難的探索,終於完成了課程的第一個作業——用masm32尋找1-100的質數,寫下此篇部落格,轉換一下心情。( • ̀ω•́ )✧ 事先宣告,我是組合語言的萌新,接下來的程式碼可能存在許多多餘和不合適的地方,而且我把所有的變

8086組合語言程式設計(二) 組合語言學習之偽指令

看到一篇講解微機原理或者組合語言蠻詳細的,因此分享給大家! 1、在計算機中數的表示方式 因為計算機中只能儲存二進位制數,所以一般都是通過二進位制直接進行儲存,但是為了方便閱讀和程式設計師的編碼簡單化,就出現了八進位制、十進位制、十

×86 (16/32位)組合語言學習——基於masm32

×86處理器中的暫存器: 組合語言必須要指明程式中的各個語句,變數該去的地方(在高階語言中這一工作由編譯器完成) 8086(16位處理器)中的暫存器 8086處理器有16根資料線和20根地址線,故可定址空間為1MB; 上圖所示為8086處理器的暫存器結構,所有的暫存器均為16位

最強大的王爽組合語言學習環境使用教程

  最強大的王爽組合語言學習環境使用教程 一、前言   這是採用VMwere Workstation 12 pro虛擬機器軟體,搭建的MS-DOS學習環境,在windowsXP/8/10及linux中均可以使用,在這個環境中,我集成了CCDOS中文系統,pdos中文系統,使

windows10中最強大王爽組合語言學習環境

一、前言   這是採用VMwere Workstation12 pro虛擬機器軟體,搭建的MS-DOS學習環境,在windowsXP/8/10及linux中均可以使用,在這個環境中,我集成了CCDOS中文系統,pdos中文系統,使用這些系統,可以進行中文輸入與顯示。還集成

組合語言學習:精華問題解答

【問題】 不理解wait指令是幹什麼用的,還有就是可不可以給棧段社標號,然後用offset獲取棧段的偏移地址呢?jmp指令只能在程式碼段中跳轉嗎,能不能跳到資料段? 【解答】 wait指令?我給你

微控制器C5152C語言組合語言學習

MCS-51微控制器的特殊功能暫存器 符號 地址 功能介紹 B F0H B暫存器 ACC E0H 累

組合語言學習之路(7)------------輸入10進位制數,將其轉換為2進位制數,存放在ax中,再將其轉換為ASCII碼並輸出

data segment        inf1 db "please input a number(1-361):$"        ibuf db 7,0,6 dup(0)        obuf db 6 dup(0)        data ends        c

32位組合語言學習筆記(32)--loop指令

 loop指令用ecx來控制迴圈次數,loop label,相當於如下兩條指令: dec ecx jne label 如下是使用loop指令的一個示例程式: section .data EditBuff: db 'abcdefghijklm',10 BUFFERL

32位組合語言學習筆記(12)--分析switch語句的彙編程式碼

switch語句可以根據整數索引值進行多重分支選擇,程式碼的可讀性好,switch語句的彙編實現是通過跳轉表來完成的,這樣執行效率也很高。int switch_eg(int x){int result = x;switch (x) {case 100:result*= 1

菜鳥的組合語言學習筆記

 1.1機器語言 計算機發展初期,人們都是用機器語言進行程式設計的,這也是人們能實現程式設計控制計算機的最低級別。那麼機器語言是什麼樣子的呢?就是用0和1組成的一個串(形如011010101),cpu的每一個功能對應著一個串,cpu得到這樣的串就去執行對應的功能,我們把這樣的串叫做一條機器指令。cpu提供的

組合語言學習

以下程式碼為自己實現,未拿書本做任何的參考,思路有不對或者不到位的地方歡迎大家指出,由於是新人,程式碼註解難免繁雜,望見諒! assume ds : datasg, cs : codesg, ss : stacksg ;show_ptr : 接受引數,在指定行,指定列顯示指

組合語言學習筆記(一)-----基礎知識

一、組合語言組成    組合語言由以下三類組成    1)彙編指令:機器碼的助記符,有對應的機器碼;    2)偽指令:沒有對應的機器碼,有編譯器執行,計算機並不執行    3)其他符號:如:+、-、*、/等,由編譯器識別,沒有對應的機器碼。二、儲存器:    CPU從記憶體

搭建x86組合語言學習環境

  設計組合語言的教學方案,決定就從8086彙編開始。   學彙編,關注對系統底層的理解,指令太多,初學者傷不起。面對一個複雜的系統,教學中常需要設計一個簡化的教學模型,抽取出其中的核心,以此得門而入。   高齡的8086彙編,於當今的技術而言,是一個理想的

32位組合語言學習筆記(21)--用NASM實現Hello World小程式

前面20篇彙編學習筆記主要是學習《深入理解計算機系統》過程中所記錄的筆記,接下來打算學一下另外一本書《Assembly Language step by step programming with linux》。首先需要安裝NASM彙編器,例如:rpm –ivh nasm-2

Win32組合語言學習筆記>>第二課:編寫第一個Win32彙編程式

本節課主要是編譯連線一段寫好的程式碼: 程式執行如下: 程式碼: .386 .model flat,stdcall option casemap:none include C:\masm32\include\windows.inc include C:\masm32\

組合語言學習第十章-CALL和RET指令

     (sp)=(sp)-2      ((ss)*16+(sp))=(IP)(IP與CS壓棧) (2) (CS)=標號處所在的段地址       (IP)=標號處所在的偏移地址 call far ptr 標號相當於: push CS push IP jmp far ptr 標號      10.

組合語言學習第十二章-內中斷

之前的除法溢位中斷是顯示Divide overflow。現在我們需要自己編寫除法溢位中斷處理程式,該程式功能是在螢幕的中間顯示字串Divide overflow。我們自己編寫的中斷處理程式暫且稱之為do0吧,中斷處理程式可能隨時被執行,我們可以使用中斷向量表的區域,中斷向量表0000:0000~0000:03

組合語言學習筆記(十二)-浮點指令

浮點數如何儲存 浮點數的運算完全不同於整數,從暫存器到指令,都有一套獨特的處理流程,浮點單元也稱作x87 FPU。 現在看浮點數的表示方式,我們所知道的,計算機使用二進位制儲存資料,所表示的數字都具有確定性,那是如何表示浮點這種具有近似效果的資料呢,答案是通過科學計數

32位組合語言學習筆記(41)--fgets等函式的使用

 在《32位組合語言學習筆記(13)--函式的呼叫》曾分析過c函式的呼叫過程,對於c函式的預設呼叫約定cdecl,要求函式引數的壓棧順序是從右向左,由呼叫方來清理棧。下面示例程式會使用libc庫的幾個函式: char *fgets( char *string, int