1. Trang chủ
  2. » Công Nghệ Thông Tin

Căn bản về lập trình ASM trên Windows

4 837 13
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Căn bản về lập trình ASM trên Windows
Tác giả Iczelion
Chuyên ngành Lập trình hợp ngữ (ASM) trên Windows
Thể loại Hướng dẫn
Định dạng
Số trang 4
Dung lượng 232,96 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Căn bản về lập trình ASM trên Windows Tổng quan về hệ thống Các ứng dụng chạy trên nền tảng hệ điều hành Windows 32-bit, nó được chạy dưới chế độ bảo vệ mà chế độ này được sử dụng từ th

Trang 1

Căn bản về lập trình ASM trên Windows Tổng quan về hệ thống

Các ứng dụng chạy trên nền tảng hệ điều hành Windows 32-bit, nó được chạy dưới chế độ bảo vệ mà chế độ này được sử dụng từ thế hệ bộ vi xử lý 80286 Nhưng bây giờ

80286 không còn được sử dụng nữa Vì vậy, chúng ta chỉ quan tâm đến các thế hệ từ bộ

vi xử lý 80386 trở về sau Hệ điều hành thực thi mỗi ứng dụng trong một vùng nhớ ảo được định sẵn Điều này có nghĩa là mỗi chương trình Win32 sẽ có riêng cho mình một vùng nhớ địa chỉ đến 4GB Tuy nhiên điều này không có nghĩa là mỗi một chương trình đều được cấp 4GB vùng nhớ vật lý, mà chỉ có nghĩa là chương trình có thể định địa chỉ trên bộ nhớ trong vùng 4GB này thôi mà thôi Hệ điều hành sẽ làm điều gì đó để chương trình có thể tham chiếu đến các giá trị trong vùng nhớ trên Dĩ nhiên là chương trình sẽ phải bám vào các qui tắc mà hệ điều hành đã qui định, nếu khác nó sẽ gây ra lỗi

protection Mỗi chương trình là “độc quyền” trong vùng địa chỉ của nó Điều này trái

ngược với các chương trình chạy trên nền tảng Windows 16-bit Tất cả các chương trình

trong Windows 16-bit có thể “nhìn” thấy nhau Nhưng dưới chế độ 32-bit Điều này sẽ

giảm bớt việc thay đổi một chương trình viết đè lên CODE hay DATA của một chương trình khác

Mô hình bộ nhớ cũng khác xa 16-bit Dưới chế độ 32-bit chúng ta không cần quan

tâm đến mô hình bộ nhớ hay khái niệm đoạn (segment) trong 16-bit Chỉ có một kiểu bộ nhớ là kiểu bộ nhớ phẳng (Flat memory) Không có khái niệm “mỗi segment chứa

không quá 64KB” trong 16-bit Bộ nhớ trong chế độ 32-bit là một vùng liên tục 4GB

Điều đó cũng có nghĩa là bạn không phải quan tâm đến những thanh ghi đoạn Bạn có thể dùng bất kỳ thanh ghi đoạn nào để định một địa chỉ bất kỳ trên vùng nhớ Điều này giúp ích cho các lập trình viên rất nhiều Đây cũng là những gì giúp cho việc lập trình trên hợp ngữ 32-bit dễ dàng hơn lập trình trong C

Khi bạn lập trình hợp ngữ trong chế độ 32-bit, bạn phải biết vài quy tắc quan trọng Một trong những quy tắc đó là :

Hệ điều hành dùng các thanh ghi ESI, EDI, EBP, và EBX khi đang xử lý một tác

vụ nào đó và nó sẽ không cho phép thay đổi giá trị của các thanh ghi đó Vì vậy hãy nhớ quy tắc đầu tiên như sau : Nếu bạn dùng một trong 4 thanh ghi đó trong các hàm có thuộc

tính callback, thì đừng quên phục hồi lại giá trị trước đó của các thanh ghi đó trước khi

trả lại điều kiển cho hệ điều hành xử lý Một hàm có thuộc tính callback thì cũng đồng nghĩa rằng hàm đó được gọi bởi hệ điều hành Hiển nhiên đó là một thủ tục của Windows,

gọi là Windows Procedure Điều này không có nghĩa là bạn không được dùng một trong

4 thanh ghi trên, bạn vẫn có thể sử dụng nhưng chắc rằng bạn sẽ phục hồi lại giá trị cho

nó trước khi bạn chuyển quyền điều khiển chương trình cho hệ điều hành

Trang 2

Lập trình ASM 32-bit

Đây là phát họa của một chương trình hợp ngữ trên nền 32-bit Nếu bạn không hiểu những gì sau đây bạn đừng quá bối rối Tôi sẽ giải thích cặn kẽ ở các bài viết sau

Chúng ta hãy cùng nhau phân tích ý nghĩa của các dòng lệnh trên!

.386  Đây là một chỉ thị nhằm nói cho MASM biết rằng chương trình của bạn đang sử

dụng cấu trúc bộ lệnh 80386 Bạn có thể dùng 486 hay 586 nhưng an tòan nhất hãy bám vào cấu trúc 386 Trong thực tế có hai cấu trúc gần giống nhau về hình thức cho mỗi kiểu

CPU .386/.386p, 486/.486p Chữ “p”(viết tắc của từ privileged : có nghĩa là được ưu

tiên), có nghĩa là chỉ khi nào cần thiết thì chương trình của bạn được ưu tiên sử dụng một

số chỉ thị của bộ lệnh này Những chỉ thị đó là những chỉ thị được dịch ngược lại bởi CPU khi nó đang họat động chế độ bảo vệ Phần lớn các chương trình của bạn làm việc trong

chế độ Non-p vì vậy để an tòan hãy dùng phiên bản Non-p

.MODEL FLAT, STDCALL

.MODEL chỉ rõ kiểu bộ nhớ đang sử dụng cho chương trình Lưu ý rằng chỉ có duy nhất

một kiểu bộ nhớ trên nền Win32 đó là flat memory, kiểu bộ nhớ này nó không phụ thuộc

vào loại ứng dụng mà bạn đang phát triển (Standard EXE, DLL, static library, console, ) Điều này cũng nói cho chúng ta biết rằng, bạn không cần quan tâm đến kiểu bộ nhớ hoặc phân đoạn giống như chúng ta đã từng làm ngày trước trên nền 16bit

STDCALL sẽ thông báo cho MASM biết cách truyền các tham số cho các hàm là như thế

nào Quy ước truyền tham số chỉ ra thứ tự của tham số được truyền là từ trái qua phải hay

từ phải qua trái và cũng chính nó cân bằng trạng thái (thứ tự) ngăn xếp khi hàm được gọi

Trang 3

Dưới chế độ 16-bit, 2 ngôn ngữ C và Pascal có quy ước truyền tham số như sau :

 Qui ước trong C : truyền tham số từ phải sang trái, điều này có nghĩa tham số bên

phải ngoài cùng sẽ được PUSH vào STACK trước tiên Hàm gọi thủ tục (caller) phải chịu trách nhiệm cân bằng cấu trúc STACK sau khi gọi

Ví dụ, để gọi một hàm có tên là :

Tên_hàm (<kiểu dữ liệu> tham số thứ 1, <kiểu dữ liệu> tham số thứ 2,

<kiểu dữ liệu> tham số thứ 3)

theo qui ước trong C, thì code asm sẽ như sau:

push [tham số thứ 3] ; Đẩy tham số thứ 3 vào ngăn xếp đầu tiên

push [tham số thứ 2] ; Kế tiếp đến tham số thứ 3

push [tham số thứ 1] ; Sau cùng là tham số thứ 1

call Tên_hàm ; Lời gọi hàm thực thi

add sp, 12 ; Cân bằng trạng thái của ngăn xếp

 Qui ước trong Pascal : ngược lại quy ước trong C Nó truyền tham số từ trái sang

phải Và hàm bị gọi (Callee) có nhiệm vụ cân bằng STACK sau khi gọi

Win-16bit chấp nhận quy ước trong Pascal bởi vì nó phát sinh ra những đoạn code nhỏ Quy ước trong C thì thường dùng khi bạn không biết bao nhiêu tham số được truyền cho

hàm như trong trường hợp hàm wsprintf() Trong trường hợp này, hàm sẽ không có cách

nào xác định được có bao nhiêu tham số sẵn sàng để đẩy (PUSH) vào ngăn xếp (STACK), vì vậy nó không thể nào làm chức năng cân bằng STACK

STDCALL là quy ước “ngoại lai” của hai quy ước gọi hàm trong C và Pascal Nó truyền

tham số từ phải sang trái, nhưng hàm bị gọi (Callee) sẽ chịu trách nhiệm cân bằng

STACK sau khi gọi Win32 platform dùng độc quyền STDCALL Ngọai trừ 1 trường hợp: wsprintf() Bạn phải dùng quy ước gọi hàm trong C với hàm wsprintf()

.DATA

.DATA?

.CONST

.CODE

Tất cả 4 chỉ thị trên được gọi là Section (đoạn) Bạn không có khái niệm segments trong Win32 (khái niệm này chỉ có trong Win16), hãy nhớ kỹ điều đó Nhưng bạn có thể chia

toàn bộ vùng địa chỉ của bạn thành những Logical Section Đầu của một section là đích của một section kế tiếp Có 2 nhóm section : data và code

Trang 4

Data sections được chia ra làm 3 lọai :

.DATA – chỉ rõ đây là section dành cho dữ liệu và dữ liệu (cụ thể là các biến) được gán

giá trị khởi tạo ngay từ đầu chương trình của bạn

.DATA? – chỉ rõ đây là section chứa dữ liệu không được gán giá trị khởi tạo Đôi khi bạn

muốn chỉ định vài vùng nhớ nhưng không muốn cho nó chứa giá trị nào lúc khởi tạo

Section này dành cho mục đích đó Lợi thế của chỉ thị này là : không chiếm khoảng trống

trong file thực thi (hay nói cách khác kích thước của file trên đĩa không tăng khi sử dụng

chỉ thị này để chứa dữ liệu)

Ví dụ : Nếu bạn chỉ định 10.000 Bytes (10 KB) trong khai báo DATA? section, file exe

của bạn sẽ không tăng thêm 10.000 Bytes Kích thước của nó sẽ không nhiều như vậy Ở

đây bạn chỉ nói cho asm biết khoảng trống bao nhiêu bạn cần khi chương trình được load

vào bộ nhớ

.CONST – chỉ rõ đây là section chứa hằng số được dùng trong chương trình của bạn

Những hằng số trong section này sẽ không thay đổi

Chú ý : Bạn không phải sử dụng cả 3 section trên trong chương trình của bạn Chỉ khai báo những section nào bạn muốn dùng

Chỉ có 1 section cho code đó là CODE Đây là nơi chứa code chương trình của bạn

<label> :

end <label>

Ở đây <label> là một nhãn bất kỳ được dùng để chỉ định khỏang rộng của code bạn Hai

nhãn <label> trên , dưới phải giống nhau Tất cả các code của bạn phải được đặt trong

<label>end <label>

01 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

02 ; Hello.asm

03 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

04 .386

05 .model flat,stdcall

06 option casemap:none

07 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

08 include windows.inc

09 include user32.inc

10 includelib user32.lib

11 include kernel32.inc

12 includelib kernel32.lib

13 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

14 .data

15 szCaption db 'A MessageBox !' , 0

16 szText db 'Hello, World !' , 0

17 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Ngày đăng: 08/11/2013, 01:15

TỪ KHÓA LIÊN QUAN

w