Tôi xin giới thiệu một chương trình nhỏ viết bằng assembly để cộng và trừ các số nguyên. Các thanh ghi (registers) được sử dụng để lưu giữ dữ liệu trung gian, chúng ta gọi các chương trình con từ thư viện (library subroutine) để hiển thị nội dung của các thanh ghi. Và đây là source code:
TITLE Add and Subtract (AddSub.asm)
; This program adds and subtracts 32-bit integers.
INCLUDE Irvine32.inc
.code
main PROC
mov eax, 10000h ; EAX = 10000h
add eax, 40000h ; EAX = 50000h
sub eax, 20000h ; EAX = 30000h
call DumpRegs ; display registers
exit
main ENDP
END main
Chúng ta sẽ lần lượt phân tích chương trình từng dòng một. Mỗi dòng của program code sẽ xuất hiện trước lời giải thích cho dòng đó.
TITLE Add and Subtract (AddSub.asm)
TITLE directive đánh dấu toàn bộ dòng này như là một comment. Bạn có thể đặt bất cứ thứ gì trên dòng này.
; This program adds and subtracts 32-bit integers.
Tất cả text phía bên phải của dấu chấm phải được assembler lờ đi, vì vậy tôi sử dụng nó cho comments.
INCLUDE Irvine32.inc
INCLUDE directive sao chép tất cả các định nghĩa cần thiết và thông tin cài đặt từ một text file có tên là Irvine32.inc, đặt nó (các định nghĩa và thông tin) trong thư mục INCLUDE của assembler (việc mô tả file này sẽ được đề cập trong các bài viết sau này)
.code
.code directive đánh dấu điểm bắt đầu của code segment, nơi tất cả các câu lệnh có thể thực thi được trong chương trình được đặt vào.
main PROC
PROC directive nhận diện sự bắt đầu của một thủ tục (procedure). Một cái tên được chọn cho một thủ tục duy nhất trong chương trình của chúng ta là main.
mov eax, 10000h ; EAX = 10000h
Lệnh MOV di chuyển (sao chép ) số nguyên 10000h đến thanh ghi EAX. Toán hạng đầu tiên (EAX) được gọi là toán hạng đích (destination operand), và toán hạng thứ hai được gọi là toán hạng nguồn (source operand). Comment phía bên tay phải hiển thị giá trị được mong đợi trong thanh ghi EAX.
add eax, 40000h ; EAX = 50000h
Lệnh ADD cộng 40000h vào thanh ghi EAX. Comment hiển thị giá trị được mong đợi trong thanh ghi EAX.
sub eax, 20000h ; EAX = 30000h
Lệnh SUB trừ giá trị thanh ghi EAX cho 20000h.
call DumpRegs ; hiển thị các thanh ghi
Câu lệnh CALL gọi một thủ tục để hiển thị các giá trị hiện hành của các thanh ghi CPU. Đây là một cách hữu dụng để xác minh xem chương trình có làm việc chính xác hay không.
exit
main ENDP
Câu lệnh exit (gián tiếp ) gọi một hàm MS-Windows đã được định nghĩa để tạm ngưng chương trình.
ENDP directive đánh dấu kết thúc của thủ tục main.
Chú ý rằng exit không là một từ khóa của MASM; thay vào đó, nó là một macro command được định nghĩa trong Irvine32.inc include file cung cấp một cách đơn giản để kết thúc chương trình.
END main
END directive đánh dấu dòng cuối của chương trình được assembled. Nó nhận dạng tên của thủ tục bắt đầu chương trình (program's startup procedure) (thủ tục bắt đầu thực thi chương trình)
Program Output
EAX = 00030000 EBX = 7FFDF000 ECX = 00000101 EDX = FFFFFFFF
ESI = 00000000 EDI = 000000000 EBP = 0012FFF0 ESP = 0012FFC4
EIP = 00401024 EPL = 000000206 CF =0 SF = 0 ZF = 0 OF = 0 AF = 0 PF = 1
Hai dòng đầu của output hiển thị các giá trị hexadicimal của cách thanh ghi mục đích chung (general-purpose registers). EAX bằng 00030000h, giá trị được sinh ra bởi các lênh ADD và SUB trong chương trình. Giá trị của các thanh ghi mục đích chung khác là không quan trọng, bởi vì giá trị của chúng không được set bởi chương trình của chúng ta. Cột thứ 3 hiển thị giá trị của các thanh ghi EIP (con trỏ lệnh mở rộng) và EFL (các cờ mở rộng), cũng như là giá trị của các cờ Carry, Sign, Zero, Overfow, Auxilary Carry, và Parity.
Không có nhận xét nào:
Đăng nhận xét