MỚI NHẤT

Chủ Nhật, 18 tháng 5, 2014

HOME ,
[ASSEMBLY] In một số nguyên dương bất kỳ

[ASSEMBLY] In một số nguyên dương bất kỳ

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!!!
Facebook ()
Blogger (0)

0 nhận xét:

Đăng nhận xét

Bài mới hơn
Bài đăng Mới hơn
Bài cũ hơn
Bài đăng Cũ hơn