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

Chia sẻ: Buihuu Tan | Ngày: | Loại File: PDF | Số trang:4

0
256
lượt xem
101
download

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

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

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.

Chủ đề:
Lưu

Nội dung Text: Căn bản về lập trình ASM trên Windows

  1. Iczelion’s Tutorial Win32 ASM Tutorial 1 : The Basic 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. Người dịch: Benina (REA TEAM) Trang 1 Tổng hợp và hiệu chỉnh: NhatPhuongLe (VNCERT TEAM)
  2. Iczelion’s Tutorial Win32 ASM Tutorial 1 : The Basic 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. Người dịch: Benina (REA TEAM) Trang 2 Tổng hợp và hiệu chỉnh: NhatPhuongLe (VNCERT TEAM)
  3. Iczelion’s Tutorial Win32 ASM Tutorial 1 : The Basic 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 ( tham số thứ 1, tham số thứ 2, 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. Người dịch: Benina (REA TEAM) Trang 3 Tổng hợp và hiệu chỉnh: NhatPhuongLe (VNCERT TEAM)
  4. Iczelion’s Tutorial Win32 ASM Tutorial 1 : The Basic 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. : end Ở đây 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 trên , dưới phải giống nhau. Tất cả các code của bạn phải được đặt trong và end . 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 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 18 .code 19 start: 20 invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK 21 invoke ExitProcess,NULL 22 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 23 end start Người dịch: Benina (REA TEAM) Trang 4 Tổng hợp và hiệu chỉnh: NhatPhuongLe (VNCERT TEAM)
Đồng bộ tài khoản