0

我正在尝试用 NASM 进行汇编代码,非常沮丧……基本上我所坚持的是将输入的数字更改为用 $ 符号绘制的更大数字。所以程序所做的就是读取一个介于 1 和 9 之间的数字并将其转换为数值并显示一个大的 $​​ 数字。我为每一行的每个数字定义了一个位模式,以显示用于绘制数字的 $ 符号模式。所有数字的大小都是 7 行,现在我需要逐步浏览位模式,这就是我卡住的地方。到目前为止,这是我的程序。

            bits    16
            org     0x100
            jmp     main    ;Jump to main program
message:    db      'Please enter a number(1-9)',0ah,0dh,'$'
enl_num1:   db      06h,06h,06h,06h,06h,06h,06h ; enlarged 1
enl_num2:   db      04h,0Ah,11h,02h,04h,08h,1Fh ; enlarged 2
enl_num3:   db      0Eh,11h,06h,18h,06h,01h,1Eh ; enlarged 3
enl_num4:   db      01h,02h,04h,0Ah,1Fh,02h,02h ; enlarged 4
enl_num5:   db      1Fh,10h,1Ch,02h,01h,02h,1Ch ; enlarged 4
enl_num6:   db      01h,02h,04h,08h,14h,14h,08h ; enlarged 5
enl_num7:   db      1Fh,01h,02h,04h,08h,10h,10h ; enlarged 7
enl_num8:   db      04h,0Ah,0Ah,04h,0Ah,0Ah,04h ; enlarged 8
enl_num9:   db      0Eh,11h,11h,0Fh,01h,01h,1Fh ; enlarged 9
error_mess: db      '**','$'
output_0:   db      ' ' 
output_d:   db      '$'     

str_to_num:
            xor     bh,bh   ;bh = 0
            cmp     al,39h  ;ASCII for 9
            jg      str_to_num_error    ; > 9 is invalid
            sub     bl,30h  ;convert to numeric
            jl      str_to_num_error    ; < 0 also invalid
            mov     bh,1h   ;succesful completion
str_to_num_error:
            ret             ;return
error:      
            mov     dx,error_mess ;adding ** to number that is not 1-9
            mov     ah,09         ;to display string
            int     21h           ;DOS interrupt
            jmp     message
            ret                   ;return

print_num:  
            mov     cx,8    ; cx=8 loop counter
            mov     al,[si] ;move one byte into al
            push    ax      ;push onto stack
            inc     si      ;point to next byte
            cmp     dh,0    ;test for 0
            jne     not_0
            je      is_0
            loop    print_num   ;decrement cx, repeat loop if cx <>0
            db      ' ',0ah,0dh,'$'
            mov     ah,09   ;to display string
            int     21h     ;DOS interrupt

            ret
not_0:      mov     dx,output_d  ;address of output
            mov     ah,09        ;service - display message
            int     21h          ;DOS system call
            ret
is_0        mov     dx,output_0  ;address of output
            mov     ah,09        ;service - display message
            int     21h          ;DOS system call
            ret

main:       mov     al,00   ;clear the screen
            mov     ah,06
            mov     bh,17h  ;white on blue
            mov     dh,05   ;set row to 5
            mov     dl,10   ;set column to 10
            int     10h     ;screen handling
            mov     dx,message
            mov     ah,09   ;to display string
            int     21h     ;DOS interrupt to display string
            mov     ah,07   ;single char keyboard input
            int     21h     ;DOS interrupt
            call    str_to_num ;convert str to num
            cmp     bh,1h   ;test if bh contains 1
            call    error   ;print error
            cmp     bh,0h   ;test if bh contains 0
            mov     si,bl   ;si contains address of number string
line_loop:  mov     cx,7    ;once for each line
            jmp     print_num ;print the number
            loop    line_loop ;decrement cx, repeat if cx<>0
            int     20h
4

1 回答 1

1

Psuedo-code for how to display one of your 8*7 characters:

ptr = &enl_num1 + (number-1)*7
for row = 0..6 do
  mask = 80h     // start with the left-most bit
  for column = 0..7 do
    if ptr[row] AND mask then
      put_char('$')
    else
      put_char(' ')
    mask >>= 1
  end for
  put_string("\n")
end for

By the way, this isn't going to work:

loop    print_num   ;decrement cx, repeat loop if cx <>0
db      ' ',0ah,0dh,'$'
mov     ah,09   ;to display string
int     21h     ;DOS interrupt

If you interleave data with code you need to jump past the data, otherwise the processor will try to execute the data as if it was code.

于 2013-04-24T10:09:38.560 回答