Thứ Bảy, 17 tháng 5, 2014

Trong lập trình hợp ngữ, nhiều lúc bạn muốn thực hiện phép nhân hoặc chia nhưng kết quả lại lưu ở trong thanh ghi AX, và bạn lúng túng không biết in chúng ra như thế nào?! Trong bài này tôi sẽ hướng dẫn các bạn 2 cách đơn giản để in ra 1 số bất kỳ (số nguyên dương, 16bit) trong AX.
[ASSEMBLY] In một số nguyên dương bất kỳ


Với cùng 1 tư tưởng đó là: chia số muốn in thành các chữ số riêng biệt, rồi in từng chữ số đó như 1 ký tự bình thường

Nhắc lại: lệnh DIV 
Cú pháp DIV reg   ; AX = AX / reg => kết quả phép chia nguyên lưu vào AX, số dư lưu vào DL

Cách 1: Duyệt các chữ số từ hàng đơn vị, lưu chúng vào Stack rồi in ngược lại

Với cách này chúng ta chia số muốn in thành các chữ số, thực hiện từ chữ số hàng đơn vị cho đến các chữ số có trọng số cao hơn. Để thực hiện ta tiến hành dùng lệnh DIV để lấy ra số dư phép chia AX cho 10 - chính là chữ số hàng đơn vị của AX. Chữ số này sẽ được cất trong Stack, trở thành đáy Stack (trong phạm vi của thủ tục này), quá trình này lặp lại đến khi AX bằng 0, chữ số có trọng số cao nhất sẽ là đỉnh stack, sẽ được in ra đầu tiên.
Dùng biến CX để đếm số ký tự trong số, phục vụ cho việc lặp in.
[ASSEMBLY] In một số nguyên dương bất kỳ

Để in ra, ta lần lượt lấy các giá trị trong Stack  rồi in chúng như những ký tự bình thường. Việc in sẽ thực hiện từ chữ số có trọng số cao nhất đến chữ số có trọng số thấp nhất (hàng đơn vị). Số lần in sẽ do CX kiểm soát.

Code cụ thể như sau:
; In 1 so bat ky o AX
PrintNums MACRO
LOCAL next, exit, print
PUSH BX ; Cat cac gia tri vao stack
PUSH CX
PUSH DX

MOV BX, 10 ; So chia
XOR CX, CX ; MOV CX, 0
next:
CMP AX, 0
JE exit ; Neu AX = 0 thi dung lai
XOR DX, DX ; MOV DX, 0
DIV BX
PUSH DX ; DX la so du cua phep chia
INC CX ; Tang CX
JMP next ; Lap lai
exit:
MOV AH, 2

print:
XOR DL, DL ; MOV DL, 0
POP DX
OR DL, 30h ; Chuyen so thanh ma ASCII tuong ung
INT 21h
LOOP print ; Lap den khi nao CX = 0

POP DX
POP CX
POP BX
ENDM

Cách 2: Duyệt các chữ số từ hàng cao nhất đến hàng đơn vị, in trực tiếp (không dùng Stack)

Cũng dùng phép chia để phân tách số ban đầu thành các chữ só riêng biệt nhưng lần này lấy kết quả để in trực tiếp (không lấy in số dư như cách trên). Việc in sẽ tiến hành từ ký tự có trọng số cao nhất đến hàng đơn vị.
Trong mỗi bước ta chia AX cho BX = 10000, sau đó giảm BX xuống còn 1000, 100, 10, 1 (cũng dùng phép chia để giảm BX). 
Dùng CX để lưu trạng thái, tránh việc in những số 0 ở đầu kết quả.

Code cụ thể như sau:
Print PROC
MOV CX, 1 ; Co danh dau
MOV BX, 10000
Begin_Print:
CMP BX, 0
JE End_Print ; BX = 0

CMP CX, 0
JE Calc ; CX = 0

CMP AX, BX
JB Skip ; AX < BX
Calc:
MOV CX, 0
MOV DX, 0
DIV BX ; AX = DX AX / BX
PrintText AL ; In AL nhu 1 ky tu binh thuong
MOV AX, DX

Skip: ; Giam BX 10 lan
PUSH AX
MOV DX, 0
MOV AX, BX
DIV ten
MOV BX, AX
POP AX
JMP Begin_Print

End_Print:
Print ENDP

Phần PrintText
; Macro in text
PrintText MACRO n
PUSH AX
PUSH DX
MOV DL, n
OR DL, 30h ; Chuyen so thanh ma ASCII tuong ung
MOV AH, 2
INT 21h
POP DX
POP AX
ENDM


Chúc bạn thành công!!!

0 nhận xét:

Đăng nhận xét

Categories

Sample Text

Được tạo bởi Blogger.

Must Read

Biểu mẫu liên hệ

Tên

Email *

Thông báo *

Popular Posts

Video

Popular Posts

Our Facebook Page