web-dev-qa-db-ja.com

x86アセンブリ言語でループを作成する方法は?

私はこれまでにコードを書きました:

.code

main
 Clrscr

  mov dh,10            ;row 10

  mov dl,20            ;column 20

  call Gotoxy          ;locate cursor

  PromptForIntegers  

    WriteString       ;display string
    ReadInt           ;input integer
  ArraySum

    WriteString       ;display string
    WriteInt          ;display integer

DisplaySum  ENDP

END main

ループを使用して同じステップを3回繰り返し、各ループの反復後に画面をクリアするにはどうすればよいですか?

16
user267288
mov cx,3

loopstart:
   do stuff
   dec cx          ;Note:  decrementing cx and jumping on result is
   jnz loopstart   ;much faster on Intel (and possibly AMD as I haven't
                   ;tested in maybe 12 years) rather than using loop loopstart
19

さらに別の方法では、LOOP命令を使用します。

mov  cx, 3

myloop:
    ; Your loop content

    loop myloop

ループ命令は自動的にcxをデクリメントし、cx!= 0の場合にのみジャンプします。ループを早期にブレークアウトするための追加チェックを行う場合は、LOOPEおよびLOOPNEバリアントもあります。

ループ中にcxを変更する場合は、ループのコンテンツの前にcxをスタックにプッシュし、次の後にポップするようにしてください。

mov  cx, 3

myloop:
    Push cx
    ; Your loop content
    pop  cx

    loop myloop
12
Jeff B

CXレジスタを使用してループをカウントします

 mov cx、3 
 startloop:
 cmp cx、0 
 jz endofloop 
 cx 
 loopy:[.____。を押します。 ] ClrScr 
 pop cx 
 dec cx 
 jmp startloop 
 endofloop:
;を呼び出します。ループが終了しました
;ここでしなければならないことを何でもします

これは、ClrScrを呼び出して3回ループし、CXレジスタをスタックにプッシュし、0と比較して、ZeroFlagが設定されている場合はジャンプし、endofloopにジャンプします。ループのフローを維持するために、CXのコンテンツがスタックにプッシュ/ポップされる方法に注目してください。

2
t0mm13b

私は同じ答えを探していましたが、wikiからのこの情報が有用であることがわかりました:ループ手順

ループ命令はECXをデクリメントし、ECXをデクリメントして値がゼロにならない限り、argで指定されたアドレスにジャンプします。例えば:

 mov ecx, 5
 start_loop:
 ; the code here would be executed 5 times
 loop start_loop

ループはフラグを設定しません。

loopx arg

これらのループ命令は、ECXをデクリメントして値がゼロにならない限り、ECXをデクリメントし、条件が満たされた場合(つまり、特定のフラグが設定されている場合)argで指定されたアドレスにジャンプします。

  • loopeループが等しい場合

  • loopne等しくない場合のループ

  • loopnzゼロでない場合のループ

  • loopzループがゼロの場合

ソース: X86アセンブリ、制御フロー

0
Pranav Singh

条件付きjmpコマンドを使用する必要があります。これは、使用している構文とは異なります。 MASMのように見えますが、GASを使用して、gcdを計算するために作成したコードの例を次に示します。

gcd_alg:
    subl    %ecx, %eax      /* a = a - c */
    cmpl    $0, %eax        /* if a == 0 */
    je      gcd_done        /* jump to end */
    cmpl    %ecx, %eax      /* if a < c */
    jl      gcd_preswap     /* swap and start over */
    jmp     gcd_alg         /* keep subtracting */

基本的に、2つのレジスタをcmpl命令と比較します(長い比較)。小さい場合、JL(jump less)命令は事前スワップ位置にジャンプします。それ以外の場合は、同じラベルに戻ります。

画面のクリアについては、使用しているシステムによって異なります。

0
user257111