【问题标题】:ASM programming, how to use loop?ASM编程,如何使用循环?
【发布时间】:2010-04-24 01:14:52
【问题描述】:

我是第一次来这里。我是一名大学生。我使用汇编语言创建了一个简单的程序。我想知道我是否可以使用循环方法来运行它,就像它在我发布的程序下面所做的一样。我也渴望找到可以通过 MSN Messenger 交谈的人,这样我就可以马上问你问题。(如果可能的话) 好的,谢谢


.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

【问题讨论】:

    标签: assembly loops tasm


    【解决方案1】:

    ...你的意思是使用循环?你已经是了。两次。

    或者您的意思是使用 LOOP 指令?如果这是你的目标,我会说不要打扰。最近我听说,这些天来,LOOP 在大多数处理器上都比同等的 dec、compare 和 branch 慢。除此之外,在您的情况下,1 和 0 是特殊的(除以 1 将始终有效,抛出您的逻辑,并且除以 0 会导致错误),并且它使您不值得花时间循环。

    【讨论】:

    • 根据我对类似案例的经验,我倾向于认为这个程序只是从某个地方复制而来的,而 chris 并不真正了解其中的内容以及它的作用和方式。 :-))
    • 我不知道为什么会有如此冒犯的回复。我认为这个网站可以互相帮助。如果您不想在这里得到帮助,请 gtfo。
    • @chris - 欢迎来到 StackOverflow 并祝大会好运。在 Fyodor 看来,帮助和做别人的(家庭)工作之间只有一线之隔。你的问题很重要,所以如果人们希望你自己学习并提出精确、谨慎的问题,请不要生气。祝你好运!
    【解决方案2】:

    我不是汇编专家,但我认为您在汇编中循环的方式是有限(迭代):定义最大循环数并增加一个值以进行比较,每次用 je 完成它。

    条件循环是一样的,但不是递增一个数字,而是将预定义的值与另一个值进行比较并以 je 结尾,这样它就会循环直到你达到你想要的为止。

    虽然我有点赶时间,但我没有仔细查看您的代码,如果这不是您所提到的,请见谅。

    编辑:当然你不必使用跳转 if equal 指令,你也可以根据情况使用 not equal 或任何其他指令。

    编辑2:呵呵忘记了最基本的,只是跳回循环的开头进行无限循环。虽然你可能想要一些东西来打破它,所以它不是很常见:)

    【讨论】:

    • 递增和使用 je 涉及一个额外的指令 - cmp。你最好减少你的计数器寄存器并做一个 jnz 或变体(跳转到不为零 - 当寄存器达到零时设置零(Z)标志)。
    • 好的,感谢您的快速回复。我想我会坚持下去。谢谢
    • 他说什么 - 正如我所说,我不是装配专家,甚至没有考虑过:)
    • 在宏伟计划中的一个额外指令并不重要。许多做 asm 的人往往是纯粹主义者,他们做 asm 的原因之一是他们希望事情尽可能紧凑和优化。所以我只是想我会指出这一点:)
    猜你喜欢
    • 2022-06-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 2015-12-24
    • 2011-12-08
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    相关资源
    最近更新 更多