[Assembly] Hướng dẫn sử dụng Emu8086 [Lập trình hợp ngữ]


[Assembly] Hướng dẫn sử dụng Emu8086 [Lập trình hợp ngữ]


Ngôn ngữ assembly (còn gọi là hợp ngữ) là một ngôn ngữ bậc thấp được dùng trong việc viết các chương trình máy tính. Ngôn ngữ assembly sử dụng các từ có tính gợi nhớ, các từ viết tắt để giúp ta dễ ghi nhớ các chỉ thị phức tạp và làm cho việc lập trình bằng assembly dễ dàng hơn. Mục đích của việc dùng các từ gợi nhớ là nhằm thay thế việc lập trình trực tiếp bằng ngôn ngữ máy được sử dụng trong các máy tính đầu tiên thường gặp nhiều lỗi và tốn thời gian. Một chương trình viết bằng ngôn ngữ assembly được dịch thành mã máy bằng một chương trình tiện ích được gọi là assembler (Một chương trình assembler khác với một trình biên dịch ở chỗ nó chuyển đổi mỗi lệnh của chương trình assembly thành một lệnh Các chương trình viết bằng ngôn ngữ assembly liên quan rất chặt chẽ đến kiến trúc của máy tính. Điều này khác với ngôn ngữ lập trình bậc cao, ít phụ thuộc vào phần cứng.

 Trước đây ngôn ngữ assembly được sử dụng khá nhiều nhưng ngày nay phạm vi sử dụng khá hẹp, chủ yếu trong việc thao tác trực tiếp với phần cứng hoặc hoặc làm các công việc không thường xuyên. Ngôn ngữ này thường được dùng cho trình điều khiển (tiếng Anh: driver), hệ nhúng bậc thấp (tiếng Anh: low-level embedded systems) và các hệ thời gian thực. Những ứng dụng này có ưu điểm là tốc độ xử lí các lệnh assembly nhanh.




* Tài liệu hướng dẫn sử dụng Emu8086 [Download tại đây]



* CLIP HƯỚNG DẪN SỬ DỤNG EMU8086


* Download công cụ lập trình Assembly tại đây
* Download tài liệu học Assembly tại đây

[Assembly] Code Assebmbly: In ra màn hình dãy Fibonacci

Ví dụ Assembly: In ra màn hình dãy Fibonacci



; fibo.asm
; assemble using nasm: 
; nasm -o fibo.com -f bin fibo.asm
;
;****************************
; Alterable Constant
;****************************
; You can adjust this upward but the upper limit is around 150000 terms.
; the limitation is due to the fact that we can only address 64K of memory
; in a DOS com file, and the program is about 211 bytes long and the
; address space starts at 100h.  So that leaves roughly 65000 bytes to
; be shared by the two terms (num1 and num2 at the end of this file).  Since
; they're of equal size, that's about 32500 bytes each, and the 150000th
; term of the Fibonacci sequence is 31349 digits long.
;
maxTerms    equ 15000 ; number of terms of the series to calculate

;****************************
; Number digits to use.  This is based on a little bit of tricky math.
; One way to calculate F(n) (i.e. the nth term of the Fibonacci seeries)
; is to use the equation int(phi^n/sqrt(5)) where ^ means exponentiation
; and phi = (1 + sqrt(5))/2, the "golden number" which is a constant about
; equal to 1.618.  To get the number of decimal digits, we just take the
; base ten log of this number.  We can very easily see how to get the
; base phi log of F(n) -- it's just n*lp(phi)+lp(sqrt(5)), where lp means
; a base phi log.  To get the base ten log of this we just divide by the
; base ten log of phi.  If we work through all that math, we get:
;
; digits = terms * log(phi) + log(sqrt(5))/log(phi)
;
; the constants below are slightly high to assure that we always have
; enough room.  As mentioned above the 150000th term has 31349 digits,
; but this formula gives 31351.  Not too much waste there, but I'd be
; a little concerned about the stack!
;
        digits     equ (maxTerms*209+1673)/1000

; this is just the number of digits for the term counter
cntDigits   equ 6 ; number of digits for counter

        org     100h            ; this is a DOS com file
;****************************
main:
; initializes the two numbers and the counter.  Note that this assumes
; that the counter and num1 and num2 areas are contiguous!
;
mov ax,'00' ; initialize to all ASCII zeroes
mov di,counter ; including the counter
mov cx,digits+cntDigits/2 ; two bytes at a time
cld ; initialize from low to high memory
rep stosw ; write the data
inc ax ; make sure ASCII zero is in al
mov [num1 + digits - 1],al ; last digit is one
mov [num2 + digits - 1],al ;
mov [counter + cntDigits - 1],al

jmp .bottom ; done with initialization, so begin

.top
; add num1 to num2
mov di,num1+digits-1
mov si,num2+digits-1
mov cx,digits ;
call AddNumbers ; num2 += num1
mov bp,num2 ;
call PrintLine ;
dec dword [term] ; decrement loop counter
jz .done ;

; add num2 to num1
mov di,num2+digits-1
mov si,num1+digits-1
mov cx,digits ;
call AddNumbers ; num1 += num2
.bottom
mov bp,num1 ;
call PrintLine ;
dec dword [term] ; decrement loop counter
jnz .top ;
.done
call CRLF ; finish off with CRLF
mov ax,4c00h ; terminate
int 21h ;

;****************************
;
; PrintLine
; prints a single line of output containing one term of the
; Fibonacci sequence.  The first few lines look like this:
;
; Fibonacci(1): 1
; Fibonacci(2): 1
; Fibonacci(3): 2
; Fibonacci(4): 3
;
; INPUT:     ds:bp ==> number string, cx = max string length
; OUTPUT:    CF set on error, AX = error code if carry set
; DESTROYED: ax, bx, cx, dx, di
;
;****************************
PrintLine:
mov dx,eol ; print combined CRLF and msg1
mov cx,msg1len+eollen   ;
call PrintString ;

mov di,counter ; print counter
mov cx,cntDigits ;
call PrintNumericString

call IncrementCount ; also increment the counter

mov dx,msg2 ; print msg2
mov cx,msg2len ;
call PrintString ;

mov di,bp ; recall address of number
mov cx,digits ;
; deliberately fall through to PrintNumericString

;****************************
;
; PrintNumericString
; prints the numeric string at DS:DI, suppressing leading zeroes
; max length is CX
;
; INPUT:     ds:di ==> number string, cx = max string length
; OUTPUT:    CF set on error, AX = error code if carry set
; DESTROYED: ax, bx, cx, dx, di
;
;****************************
PrintNumericString:
; first scan for the first non-zero byte
mov al,'0' ; look for ASCII zero
cld ; scan from MSD to LSD
repe scasb ;
mov dx,di ; points to one byte after
dec dx ; back up one character
inc cx ;
; deliberately fall through to PrintString

;****************************
;
; PrintString
; prints the string at DS:DX with length CX to stdout
;
; INPUT:     ds:dx ==> string, cx = string length
; OUTPUT:    CF set on error, AX = error code if carry set
; DESTROYED: ax, bx
;
;****************************
PrintString:
mov bx, 1 ; write to stdout
mov     ah, 040h        ; write to file handle
int 21h ; ignore return value
ret ;

;****************************
;
; AddNumbers
; add number 2 at ds:si to number 1 at es:di of width cx
;
;
; INPUT:     es:di ==> number1, ds:si ==> number2, cx= max width
; OUTPUT:    CF set on overflow
; DESTROYED: ax, si, di
;
;****************************
AddNumbers:
std ; go from LSB to MSB
clc ;
pushf ; save carry flag
.top
mov ax,0f0fh ; convert from ASCII BCD to BCD
and  al,[si] ; get next digit of number2 in al
and ah,[di] ; get next digit of number1 in ah
popf ; recall carry flag
adc al,ah ; add these digits
aaa ; convert to BCD
pushf ;
add al,'0' ; convert back to ASCII BCD digit
stosb ; save it and increment both counters
dec si ;
loop .top ; keep going until we've got them all
popf ; recall carry flag
ret ;

;****************************
;
; IncrementCount
; increments a multidigit term counter by one
;
; INPUT:     none
; OUTPUT:    CF set on overflow
; DESTROYED: ax, cx, di
;
;****************************
IncrementCount:
mov cx,cntDigits ;
mov di,counter+cntDigits-1
std ; go from LSB to MSB
stc ; this is our increment
pushf ; save carry flag
.top
mov ax,000fh ; convert from ASCII BCD to BCD
and al,[di] ; get next digit of counter in al
popf ; recall carry flag
adc al,ah ; add these digits
aaa ; convert to BCD
pushf ;
add al,'0' ; convert back to ASCII BCD digit
stosb ; save and increment counter
loop .top ;
popf ; recall carry flag
ret ;

;****************************
;
; CRLF
; prints carriage return, line feed pair to stdout
;
; INPUT:     none
; OUTPUT:    CF set on error, AX = error code if carry set
; DESTROYED: ax, bx, cx, dx
;
;****************************
CRLF: mov dx,eol ;
mov cx,eollen ;
jmp PrintString ;

;****************************
; static data
;****************************
eol db  13,10 ; DOS-style end of line
eollen equ $ - eol

msg1 db  'Fibonacci(' ;
msg1len equ $ - msg1

msg2 db  '): ' ;
msg2len equ $ - msg2
;****************************
; initialized data
;****************************
term dd maxTerms ;
;****************************
; unallocated data
;
; A better way to do this would be to actually ask for a memory
; allocation and use that memory space, but this is a DOS COM file
; and so we are given the entire 64K of space.   Technically, this
; could fail since we *might* be running on a machine which doesn't
; have 64K free.  If you're running on such a memory poor machine,
; my advice would be to not run this program.
;
;****************************
; static data
counter: ;
num1 equ counter+cntDigits ;
num2 equ num1+digits ;

;***********************************************


[Thuật toán Cây quyết định] Chương trình mô phỏng thuật toán ID3 – Cây Quyết Định

[Thuật toán Cây quyết định] Chương trình mô phỏng thuật toán ID3 – Cây Quyết Định

>> Hướng dẫn lập trình C#

1. Giải thuật ID3:

ID3_algorithm(Training_Set, Class_Labels, Attributes)

Tạo nút Root của cây quyết định

   If tất cả các ví dụ của Training_Set thuộc cùng lớp c

   Return Cây quyết định có nút Root được gắn với (có nhãn) lớp c

   If Tập thuộc tính Attributes là rỗng

   Return Cây quyết định có nút Root được gắn với nhãn lớp ≡ Majority_Class_Label(Training Set)

   A ← Thuộc tính trong tập Attributes có khả năng phân loại “tốt nhất” đối với Training_Set

   Thuộc tính kiểm tra cho nút Root ← A

   For each Giá trị có thể v của thuộc tính A

 Bổ sung một nhánh cây mới dưới nút Root, tương ứng với trường hợp: “Giá trị của A là v”

   Xác định Training_Setv = {ví dụ x | x ⊆ Training_Set, xA=v}

  If (Training_Setv là rỗng) Then

  Tạo một nút lá với nhãn lớp ≡ Majority_Class_Label(Training_Set)

Gắn nút lá này vào nhánh cây mới vừa tạo

Else Gắn vào nhánh cây mới vừa tạo một cây con sinh ra bởi ID3_algorithm(Training_Setv, Class_Labels, {Attributes A})

Return Root


2. Giao diện chính của chương trình Demo gồm 4 phần:

o Phần 1: Bảng lưu dữ liệu training (Data Training).

o Phần 2: Ghi ra các bước giải của thuật toán (Solutions).

o Phần 3: Vẽ cây minh họa cho thuật toán (Decision Tree).

o Phần 4: Các chức năng của chương trình (Control).


Có 4 button với các chức năng như sau:

- Load Data: Đưa dữ liệu training vào chương trình.

- ID3 – Alg: Chạy giải thuật ID3.

- Reset: Khởi động, chạy lại chương trình.

- About: Thông tin về chương trình.





3.  Các bước chạy chương trình:

- Đầu tiên, nạp dữ liệu vào chương trình bằng button Load Data.

Dữ liệu được đưa lên bảng Data Training (Phần 1).

- Sau đó, nhấn button ID3 – Alg để chạy giải thuật.

Các bước giải sẽ được hiện ra ở phần 2 (Solutions).

Cây được vẽ ra ở phần 3 (Decision Tree).


4. Giao diện chương trình:



Chương trình gồm những hàm chính sau:

 Hàm tính Entropy:

· Công thức:    Entropy (S) = – p+ log2 p+ – p- log2 p-

· Code [C#]:

private double GetEntropy(int Positives , int Negatives)
{
if (Positives == 0)
return 0;
if (Negatives == 0)
return 0;
double Entropy;
int total = Negatives + Positives;
double RatePositves = (double)Positives / total;
double RateNegatives = (double)Negatives / total;
Entropy = -RatePositves * Math.Log(RatePositves, 2) – RateNegatives * Math.Log(RateNegatives, 2);
return Entropy;
}


 Hàm tính Gain:

· Công thức:


· Code [C#]:

private double Gain(List<List<string>> Examples, Attribute A, string bestat)
{
double result;
int CountPositives = 0;
int[] CountPositivesA = new int[A.Value.Count];
int[] CountNegativeA = new int[A.Value.Count];
int Col = Attributes.IndexOf(A);
for (int i = 0; i < A.Value.Count; i++)
{
CountPositivesA[i] = 0;
CountNegativeA[i] = 0;
}
for (int i = 0; i < Examples.Count; i++)
{
int j = A.Value.IndexOf(Examples[i][Col].ToString());
if (Examples[i][Examples[0].Count – 1]==”yes”)
{
CountPositives++;
CountPositivesA[j]++;
}
else
{
CountNegativeA[j]++;
}
}
result = GetEntropy(CountPositives, Examples.Count – CountPositives);
for (int i = 0; i < A.Value.Count; i++)
{
double RateValue = (double)(CountPositivesA[i] + CountNegativeA[i]) / Examples.Count;
result = result – RateValue * GetEntropy(CountPositivesA[i], CountNegativeA[i]);
}
Solution = Solution + “n * Gain(” + bestat + “,” + A.Name + “) = ” + result.ToString();
return result;
}



 Hàm chọn đặc tính tốt nhất:

· Phương pháp:
    - Dựa vào giá trị gain của các đặc tính, đặc tính nào có Gain lớn nhất.

    - Chọn đặc tính đó – đặc tính tốt nhất.

· Code [C#]:

private Attribute GetBestAttribute(List<List<string>> Examples, List<Attribute> Attributes, string bestat)
{
double MaxGain = Gain(Examples, Attributes[0], bestat);
int Max = 0;
for (int i = 1; i < Attributes.Count; i++)
{
double GainCurrent = Gain(Examples, Attributes[i], bestat);
if (MaxGain < GainCurrent)
{
MaxGain = GainCurrent;
Max = i;
}
}
return Attributes[Max];
}
 Hàm thực hiện giải thuật ID3:
Code:
private TreeNode ID3(List<List<string>> Examples, List<Attribute> Attribute,string bestat)
{
if (CheckAllPositive(Examples))
{
return new TreeNode(new Attribute(“Yes”));
}
if (CheckAllNegative(Examples))
{
return new TreeNode(new Attribute(“No”));
}
if (Attribute.Count == 0)
{
return new TreeNode(new Attribute(GetMostCommonValue(Examples)));
}
Attribute BestAttribute = GetBestAttribute(Examples, Attribute, bestat);
int LocationBA = Attributes.IndexOf(BestAttribute);
TreeNode Root = new TreeNode(BestAttribute);
for (int i = 0; i < BestAttribute.Value.Count; i++)
{
List<List<string>> Examplesvi = new List<List<string>>();
for (int j = 0; j < Examples.Count; j++)
{
if (Examples[j][LocationBA].ToString() == BestAttribute.Value[i].ToString())
Examplesvi.Add(Examples[j]);
}
if (Examplesvi.Count==0)
{
return new TreeNode(new Attribute(GetMostCommonValue(Examplesvi)));
}
else
{
Attribute.Remove(BestAttribute);
Root.AddNode(ID3(Examplesvi, Attribute,BestAttribute.Value[i]));
}
}
return Root;
}


(theo csshare)

[Tự học lập trình C/C++] Bài 3: Nhập / Xuất trong C/C++

---------------------------------
* TÓM TẮT LÝ THUYẾT
---------------------------------

  1. In dữ liệu ra màn hình: 
 
  cout<<data1<<data1<<...;
 
     Trong đó:     
      - data là biến, biểu thức, xâu ký tự,...     
      - Mỗi khối dữ liệu cách nhau bởi <<
       
  2. Nhập dữ liệu vào từ bàn phím: 

  cin>>var1>>var2>>...;
 
  Trong đó:  
  - var là các biến cần nhập từ bàn phím.  
  - Mỗi biến cách nhau bởi >>
      
---------------------------------
** VÍ DỤ
---------------------------------

Ví dụ 1: 

+ Yêu cầu:  Nhập vào 2 số nguyên a, b. Tính tổng, hiệu, tích, thương 2 số đó.

+ Code:

#include <iostream>
#include <conio.h>

using namespace std;

int main() {

    int a,b;
    // nhap 2 so
    cout<<"\n Nhap 2 so: ";
    cout<<"\n a= ";
    cin>>a;
    cout<<"\n b= ";
    cin>>b;
 
    // Tinh tong, hieu, tich, thuong
    int tong,hieu,tich;
    tong=a+b;
    hieu=a-b;
    tich=a*b;
    float thuong=(float)a/b;
 
    // in ket qua
    cout<<"\n Tong: "<<tong;
    cout<<"\n Hieu: "<<hieu;
    cout<<"\n Tich: "<<tich;
    cout<<"\n Thuong: "<<thuong;
 
   return 0;
}


------------

Ví dụ 2: 

+ Yêu cầu:  Nhập vào 3 cạnh tam giác, tính chu vi, diên tích tam giác đó.

+ Code:


#include <iostream>
#include <conio.h>
#include <math.h>

using namespace std;

int main() {
    float a,b,c;
    // nhap 3 canh tam giac
    cout<<"\n Nhap 3 canh: ";
    cout<<"\n a= ";
    cin>>a;
    cout<<"\n b= ";
    cin>>b;
    cout<<"\n b= ";
    cin>>b;
 
 
    // Tinh chu vi tam giac
    float cv,dt;
    cv=a+b+c;
    float p=cv/2;
    dt=sqrt(p*(p-a)*(p-b)*(p-c));
 
   // in ket qua
    cout<<"\n Chu vi: "<<cv;
    cout<<"\n Dien tich: "<<dt;
 
   return 0;
}

------------

Ví dụ 3: 

+ Yêu cầu: Tính điểm cho sinh viên:

 - Nhập vào điểm: điểm toán rời rạc (3 tín chỉ); điểm lập trình (4 tín chỉ); điểm cơ sở dữ liệu (3 tín chỉ)
 - Tính điểm tổng kết.
 - In kết quả.

 + Code:

#include <iostream>
#include <conio.h>

using namespace std;

int main() {
    float dTRR,dLT,dCSDL;
    // nhap nhap diem    
    cout<<"\n Nhap diem: ";
    cout<<"\n Diem toan roi rac: ";
    cin>>dTRR;
    cout<<"\n Diem lap trinh: ";
    cin>>dLT;
    cout<<"\n Diem co so du lieu: ";
    cin>>dCSDL;
    // Tinh diem
    float dTK;
    dTK=(dTRR*3+dLT*4+dCSDL*3)/10;
    // in ket qua
    cout<<"\n Diem tong ket: "<<dTK;
 
   return 0;
}

Một số tài liệu và khoá học bổ ích dành cho bạn: 

# Giáo Trình: Kỹ Thuật Lập Trình C/C++ Căn Bản Và Nâng Cao [Click để xem]

# Khoá học online: Học lập trình C/C++ TỪ A - Z [Click để xem]




------------------------
Xem bài khác: