ASM программирование, как использовать цикл? - PullRequest
1 голос
/ 24 апреля 2010

Я здесь впервые. Я студент колледжа. Я создал простую программу с использованием ассемблера. И я задаюсь вопросом, могу ли я использовать метод цикла, чтобы запустить его почти так же, как и в программе, которую я опубликовал. и я также хочу найти кого-то, с кем я могу общаться через MSN Messanger, чтобы я мог задать вам вопросы сразу (по возможности) хорошо, спасибо


.MODEL small
.STACK 400h

.data


prompt                 db      10,13,'Please enter a 3 digit number, example 100:',10,13,'$'    ;10,13 cause to go to next line
first_digit         db      0d
second_digit            db      0d
third_digit         db      0d
Not_prime               db      10,13,'This number is not prime!',10,13,'$'
prime                   db      10,13,'This number is prime!',10,13,'$'
question                db      10,13,'Do you want to contine Y/N $'
counter                 dw      0d
number                  dw      0d
half                    dw      ?


.code


Start:


      mov ax, @data         ;establish access to the data segment
      mov ds, ax            
      mov number, 0d        

LetsRoll:


        mov dx, offset prompt          ; print the string (please enter a 3 digit...)
        mov ah, 9h                      
        int 21h                         ;execute
                                        ;read FIRST DIGIT
    mov ah, 1d          ;bios code for read a keystroke
    int 21h             ;call bios, it is understood that the ascii code will be returned in al
    mov first_digit, al     ;may as well save a copy
    sub al, 30h         ;Convert code to an actual integer
    cbw             ;CONVERT BYTE TO WORD. This takes whatever number is in al and
                    ;extends it to ax, doubling its size from 8 bits to 16 bits
                    ;The first digit now occupies all of ax as an integer
    mov cx, 100d            ;This is so we can calculate 100*1st digit +10*2nd digit + 3rd digit
    mul cx              ;start to accumulate the 3 digit number in the variable imul cx
                    ;it is understood that the other operand is ax
                    ;AND that the result will use both dx::ax
                    ;but we understand that dx will contain only leading zeros
    add number, ax          ;save
                    ;variable <number> now contains 1st digit * 10
                    ;----------------------------------------------------------------------

                    ;read SECOND DIGIT, multiply by 10 and add in
    mov ah, 1d          ;bios code for read a keystroke
    int 21h             ;call bios, it is understood that the ascii code will be returned in al
    mov second_digit, al        ;may as well save a copy
    sub al, 30h         ;Convert code to an actual integer
    cbw             ;CONVERT BYTE TO WORD. This takes whatever number is in al and
                    ;extends it to ax, boubling its size from 8 bits to 16 bits
                    ;The first digit now occupies all of ax as an integer
    mov cx, 10d         ;continue to accumulate the 3 digit number in the variable
    mul cx              ;it is understood that the other operand is ax, containing first digit
                    ;AND that the result will use both dx::ax
                    ;but we understand that dx will contain only leading zeros. Ignore them
    add number, ax          ;save -- nearly finished
                    ;variable <number> now contains 1st digit * 100 + second digit * 10
                    ;----------------------------------------------------------------------

                    ;read THIRD DIGIT, add it in (no multiplication this time)
    mov ah, 1d          ;bios code for read a keystroke
    int 21h             ;call bios, it is understood that the ascii code will be returned in al
    mov third_digit, al     ;may as well save a copy
    sub al, 30h         ;Convert code to an actual integer
    cbw             ;CONVERT BYTE TO WORD. This takes whatever number is in al and
                    ;extends it to ax, boubling its size from 8 bits to 16 bits
                    ;The first digit now occupies all of ax as an integer
    add number, ax          ;Both my variable number and ax are 16 bits, so equal size
        mov ax, number          ;copy contents of number to ax
        mov cx, 2h          
        div cx              ;Divide by cx
        mov half, ax            ;copy the contents of ax to half
        mov cx, 2h;         
        mov ax, number;         ;copy numbers to ax
        xor dx, dx          ;flush dx
    jmp prime_check         ;jump to prime check

print_question:


        mov dx, offset question     ;print string (do you want to continue Y/N?)
        mov ah, 9h          
        int 21h             ;execute
        mov ah, 1h          
        int 21h             ;execute
        cmp al, 4eh         ;compare 
        je Exit             ;jump to exit
        cmp al, 6eh         ;compare
        je Exit             ;jump to exit 
        cmp al, 59h         ;compare
        je Start            ;jump to start
        cmp al, 79h         ;compare
        je  Start           ;jump to start

prime_check:


        div cx;             ;Divide by cx
        cmp dx, 0h          ;reset the value of dx
        je  print_not_prime     ;jump to not prime 
        xor dx, dx;         ;flush dx
        mov ax, number          ;copy the contents of number to ax
        cmp cx, half            ;compare half with cx
        je print_prime          ;jump to print prime section
        inc cx;             ;increment cx by one
        jmp prime_check         ;repeat the prime check 

print_prime:


        mov dx, offset prime        ;print string (this number is prime!)
        mov ah, 9h          
        int 21h             ;execute
        jmp print_question      ;jumps to question (do you want to continue Y/N?) this is for repeat

print_not_prime:


        mov dx, offset Not_prime    ;print string (this number is not prime!)
        mov ah, 9h          
        int 21h             ;execute
        jmp print_question      ;jumps to question (do you want to continue Y/N?) this is for repeat

Exit:


    mov ah, 4ch             
    int 21h             ;execute exit           

        END Start

Ответы [ 2 ]

1 голос
/ 24 апреля 2010

... Вы имеете в виду использовать цикл? Вы уже есть. Дважды.

Или вы имеете в виду использовать инструкцию LOOP? Если это ваша цель, я бы сказал, не беспокойтесь. Последнее, что я слышал, в эти дни, LOOP медленнее на большинстве процессоров, чем эквивалентные dec, Compare и Branch. Добавьте к этому тот факт, что в вашем случае 1 и 0 являются особыми (деление на 1 всегда будет работать, отбрасывая вашу логику, а на 0 это приведет к ошибке), и это делает его бесполезным для LOOP.

0 голосов
/ 24 апреля 2010

Я не эксперт по сборке, но я думаю, что циклы в сборке являются либо конечными (итеративными): определите максимальное количество циклов и увеличьте значение для сравнения, чтобы каждый раз заканчивать его с помощью je.

Условный цикл - это то же самое, но вместо того, чтобы увеличивать число, вы сравниваете предварительно определенное значение с другим значением и заканчиваете на je, так что цикл будет повторяться до тех пор, пока вы не достигнете желаемого.

Я не внимательно изучил ваш код, хотя я тороплюсь, так что извините, если это не то, что вы думаете.

Редактировать: конечно, вам не нужно использовать переход, если есть равные инструкции, вы также можете использовать не равные или любые другие в зависимости от ситуации.

Редактировать 2: хех забыл о самом простом, просто вернитесь к началу цикла для бесконечного цикла. Хотя вам, вероятно, захочется что-то сломать, поэтому оно не очень распространено:)

...