2012-04-02 16 views
5

Tôi đang sử dụng NASM 16 BITS. Tôi đang cố gắng để làm một mã lắp ráp đơn giản mà in các số từ 0 đến 255 với khoảng thời gian 1 giây giữa mỗi số. Đây là những gì tôi có cho đến nay:Làm thế nào để hiển thị một số trên màn hình và ngủ trong một giây với lắp ráp DOS x86?

[bits 16] 

mov ax,cs 
mov ds,ax 
mov cx,255 
mov ax,0 

myloop: 
    ;print in screen ax value 
    ;wait 1 second 
    inc ax 

loop myloop 

Tôi không chắc chắn làm thế nào để in giá trị của rìu trong màn hình, và làm thế nào để chờ đợi 1 giây (đặt chúng trong một chú thích trong code).

+0

Bạn đang thực hiện việc này trên PC? –

+0

@PavanManjunath Vâng, tôi đang thực hiện nó trên PC. Windows 7, 32 bit. –

+0

Đối với phần chậm trễ, bạn có thể kiểm tra bài viết cuối cùng trong chủ đề [this] (http://www.physicsforums.com/showthread.php?t=150424). Đồng hồ được giả định là 100 MHz. Nhưng bạn cần phải tìm ra giá trị chính xác trên máy của bạn thông qua thử và sai. [This] (http://www.programmersheaven.com/mb/x86_asm/272272/272273/re-sleep-function-/?S=B10000) liên kết cũng sẽ giúp bạn nhận được sự chậm trễ ngay –

Trả lời

6

Có bộ đếm 4 byte tại phân khúc 0 bù 46Ch (hoặc cách khác tại seg 40h, offs 6Ch) được duy trì và cập nhật bởi BIOS PC. Nó tăng 18,2 lần mỗi giây. Đếm 18 thay đổi trong byte thấp nhất hoặc lời của bộ đếm này có lẽ là cách đơn giản nhất của chờ đợi ra khoảng một giây:

mov ax, 0 
mov ds, ax 
mov cx, 18 
mov bx, [46Ch] 
WaitForAnotherChange: 
NoChange: 
mov ax, [46Ch] 
cmp ax, bx 
je NoChange 
mov bx, ax 
loop WaitForAnotherChange 

Để in số thập phân bạn cần phải chuyển đổi số nhị phân thành số thập phân, có cá nhân chữ số và in chúng . Bạn chia số cho 10 và thu thập số dư. ví dụ:

123:
123/10: thương 12, còn lại 3
12/10: thương 1, còn lại 2
1/10: thương 0, còn lại 1

Bằng cách lặp đi lặp lại chia cho 10 bạn nhận được các chữ số riêng lẻ trong các phần còn lại theo thứ tự ngược lại: 3,2,1. Sau đó, bạn in chúng bằng cách sử dụng hàm DOS int 21h 2 (tải 2 thành AH, tải mã ASCII của ký tự vào DL, thực hiện int 21h).

Một biến thể khác, khá phù hợp với vấn đề của bạn, sẽ sử dụng lệnh DAA để tăng số trực tiếp bằng số thập phân mà không cần bất kỳ chuyển đổi nào.

Dưới đây là làm thế nào nó đều có thể được thực hiện:

; file: counter.asm 
; assemble: nasm.exe counter.asm -f bin -o counter.com 

bits 16 
org 0x100 

    mov ax, 0 ; initial number 
    mov cx, 256 ; how many numbers 

NextNumber: 
%if 1 ; change to 0 to use the DAA-based method 
    push ax 

    mov dx, 0 
    div word [ten] 
    push dx 

    mov dx, 0 
    div word [ten] 
    push dx 

    mov dx, 0 
    div word [ten] 
    push dx 

    pop dx 
    call PrintDigit 
    pop dx 
    call PrintDigit 
    pop dx 
    call PrintDigit 

    pop ax 

    call PrintNewLine 
    call Wait1s 

    inc ax 
%else 
    mov dl, ah 
    call PrintDigit 

    mov dl, al 
    shr dl, 4 
    call PrintDigit 

    mov dl, al 
    and dl, 0Fh 
    call PrintDigit 

    call PrintNewLine 
    call Wait1s 

    add al, 1 
    daa 
    adc ah, 0 
%endif 

    loop NextNumber 
    ret 

PrintDigit: 
    pusha 
    mov ah, 2 
    add dl, '0' 
    int 21h 
    popa 
    ret 

PrintNewLine: 
    pusha 
    mov dx, CRLF 
    mov ah, 9 
    int 21h 
    popa 
    ret 

Wait1s: 
    pusha 
    push ds 

    mov ax, 0 
    mov ds, ax 

    mov cx, 18 
    mov bx, [46Ch] 
WaitForAnotherChange: 
NoChange: 
    mov ax, [46Ch] 
    cmp ax, bx 
    je NoChange 
    mov bx, ax 
    loop WaitForAnotherChange 

    pop ds 
    popa 
    ret 

ten dw 10 
CRLF db 13,10,"$" 

Nếu bạn không thích những zeroes hàng đầu hoặc sự chậm trễ 1 giây cuối cùng, bạn có điều kiện có thể bỏ qua chúng.

Tải xuống sách hướng dẫn CPU Intel và/hoặc AMD x86 mô tả cách hoạt động của từng lệnh. Đọc chúng. Ngoài ra, hãy tải xuống Ralf Brown's Interrupt List, mô tả mọi chức năng BIOS và DOS. Bạn cần phải biết một số người trong số họ để làm I/O. Ngoài ra còn có HelpPCTechHelp mô tả thuận tiện nhiều thứ BIOS và DOS như số BIOS Data Area trong đó bộ đếm nói trên tồn tại.

+0

Nhận xét này dành cho @Alex Nó hoạt động hoàn hảo, cảm ơn rất nhiều vì sự giúp đỡ hào phóng của bạn. Tôi chắc chắn sẽ đọc tất cả những gì bạn đã nói trong phần bình luận ở trên. Chỉ một câu hỏi, Bạn có khó sửa đổi mã bạn đã đăng để làm cho quá trình quay trở lại không? (Từ 255 đến 0). –

+0

Tôi đã làm điều đó, nhờ sự giúp đỡ của bạn một lần nữa @Alex –

+0

Nó tầm thường/dễ dàng trong cả hai trường hợp dựa trên div và daa. –

Các vấn đề liên quan