Tổng hợp các mã lệnh được dùng trong bài tập 1 khóa học Kiến trúc máy tính và Assembly


Bài tập: nhập hai số nguyên, tính tổng và in ra màn hình.

Video 1: https://youtu.be/JJTuWwFW2nc

Video 2: https://youtu.be/rKNuJ7QJt4Q

Video 3: https://youtu.be/cdmgwjOI5Rc

MOV – Di chuyển dữ liệu

Sao chép giá trị từ nguồn sang đích mà không làm thay đổi giá trị nguồn.

Ví dụ: `mov rax, 1` gán giá trị 1 vào thanh ghi rax.

Lưu ý là chúng ta không thể thực hiện một lệnh mov từ bộ nhớ đến bộ nhớ, để làm vậy bạn cần hai lệnh mov riêng biệt và dùng một thanh ghi làm nơi chứa giá trị trung gian.

Không phải thanh ghi nào cũng có thể được thay đổi giá trị bằng lệnh mov.

SYSCALL – Gọi hệ thống

Thực hiện lời gọi hệ thống của Linux.

Lệnh syscall chuyển điều khiển cho hệ điều hành, đồng thời đưa CPU về kernel mode, bạn cần gán giá trị thanh ghi rax bằng mã chức năng mà bạn muốn gọi.

Xem chi tiết trong bài: https://youtu.be/gefL014dGz8

CALL – Gọi thủ tục

Nhảy đến một hàm (thủ tục) và lưu địa chỉ trả về (giá trị của thanh ghi RIP) vào stack.

Nói cách khác, CPU sẽ push giá trị của RIP vào stack, sau đó gán lại RIP = địa chỉ hàm.

RET – Trả về

Quay trở lại địa chỉ được lưu bởi lệnh `call`.

Lệnh này được thực hiện bằng cách “pop” giá trị trên đỉnh stack vào thanh ghi RIP, tương tự như pop RIP (tuy nhiên bạn không thể thực hiện lệnh pop hay gán giá trị vào RIP một cách trực tiếp).

ADD – Cộng

Thực hiện phép cộng hai toán hạng. Ví dụ: `add rax, r12` cộng r12 vào rax (rax = rax + r12, hoặc rax += r12).

SUB – Trừ

Thực hiện phép trừ. Ví dụ: `sub rax, r12` tương đương với rax = rax – r12

IMUL – Nhân có dấu

Nhân hai số có dấu.

DIV – Chia không dấu

Chia rdx:rax (kết hợp hai thanh ghi lại thành một giá trị 128 bit) cho toán hạng. Kết quả thương nằm trong rax, phần dư nằm trong rdx.

Ví dụ:

div rcx

Khi đó: rax = rdx:rax / rcx và rdx = rdx:rax % rcx.

Lưu ý: tùy thuộc vào độ lớn bit của toán tử mà các thanh ghi tương ứng sẽ được dùng, nếu toán tử 8 bit thì các thanh ghi tương ứng. (Tham khảo: https://www.felixcloutier.com/x86/div)

PUSH – Đẩy vào stack

Lưu giá trị vào stack.

Đẩy giá trị vào stack, làm giảm con trỏ stack (thanh ghi rsp)

POP – Lấy khỏi stack

Lấy giá trị từ đỉnh stack, tăng con trỏ rsp.

CMP – So sánh

So sánh hai toán hạng và đặt cờ điều kiện tương ứng.

Bản chất của việc so sánh này là lấy toán hạng 1 trừ toán hạng 2, dựng lên các cờ tương ứng mà không lưu lại giá trị.

Ví dụ:

cmp rax, rbx

Đồng nghĩa với việc CPU thực hiện temp = rax – rbx, các cờ như Zero, Carry… sẽ được bật hoặc tắt dựa trên kết quả (temp), tuy nhiên temp sẽ không được lưu lại trong bất kỳ thanh ghi nào.

Lệnh cmp thường được kết hợp với các nhảy có điều kiện (các lệnh j*, ngoại trừ jmp).

JE – Jump if Equal

Nhảy nếu kết quả so sánh bằng nhau (ZF=1).

JNE – Jump if Not Equal

Nhảy nếu kết quả so sánh không bằng nhau (ZF=0).

INC – Tăng

Tăng giá trị lên 1.

DEC – Giảm

Giảm giá trị đi 1.

XOR

Thực hiện phép XOR trên bit.

Ta hay dùng để đưa một thanh ghi về 0 nhanh chóng, ví dụ `xor rax, rax`, lệnh này hiệu quả hơn mov rax, 0.

TEST – Kiểm tra bit

Thực hiện phép AND nhưng không lưu kết quả, dùng để kiểm tra điều kiện.

Tương tự lệnh CMP nhưng dùng phép AND thay vì phép trừ, ta thường dùng để kiểm tra một bit nào đó đang bật hoặc tắt, hoặc cũng dùng để kiểm tra một thanh ghi có khác 0 hay không.

JNZ – Jump if Not Zero

Nhảy nếu kết quả khác 0 (ZF=0).

Leave a comment