サーチ…


前書き

重要でないソフトウェアのすべてには、条件に応じてプログラムの流れをそらすためのフロー制御構造が必要です。アセンブリーは最低レベルのプログラミング言語であり、制御構造のプリミティブのみを提供します。通常、マシン操作はCPUのフラグに影響し、 条件分岐/ジャンプはフロー制御を実装します。アセンブリでは、すべての上位レベルの制御構造をそのようなプリミティブから構築する必要があります。

m68k組立での簡単なIF-THEN-ELSE

; IF d0 == 10 GO TO ten, ELSE GO TO other
    CMP    #10,d0        ; compare register contents to immediate value 10
                         ; instruction affects the zero flag
    BEQ    ten           ; branch if zero flag set
other:
    ; do whatever needs to be done for d0 != 10
    BRA    afterother    ; unconditionally jump across IF case 
ten:
    ; do whatever needs to be done for d0 == 10
afterother:
    ; continue normal common program flow

どの命令がどのフラグに影響を及ぼしているか、どの条件分岐(特定のフラグの組合せにも基づく可能性があります)が利用可能かは、選択したCPUによって大きく異なり、マニュアルで参照する必要があります。

FOR ...次のZ80アセンブリ

Z80には、ループカウントを実装するための特別な命令がありますDJNZは「Bレジスタをデクリメントし、ゼロでない場合にジャンプ」を表します。したがって、Bはこのプロセッサでループを実装するための選択レジスタです。 FOR ... NEXTは "後方に"実装する必要があります。なぜなら、レジスタはゼロまでカウントダウンするからです。他のCPU(8086のように、このCPUはループカウンタとしてCXレジスタを使用しています)には同様の特定のループカウンタレジスタと命令があります。

; Trivial multiplication (by repeated adding, ignores zero in factors, so 
; not recommended for general use)
;
; inputs:    A = Factor 1
;            B = Factor 2
;
; output:    A = Factor 1 * Factor 2
;
; Pseudo code
; C = A : A = 0 : FOR B = Factor 2 DOWNTO 0 : A = A + C : NEXT B

mul:
     LD    C,A        ; Save Factor 1 in C register
     XOR   A          ; Clear accumulator
mLoop:
     ADD   A,C        ; Add Factor 1 to accumulator
     DJNZ  mLoop      ; Do this Factor 2 times
     RET              ; return to caller

インテル構文アセンブリのIf文

section .data
    msg_eq db 'Equal', 10
    len_eq equ $ - msg_eq

    msg_le db 'Less than', 10
    len_le equ $ - msg_le

    msg_gr db 'Greater than', 10
    len_gr equ $ - msg_gr ; Length of msg_gr
section .text
    global _main ; Make the _main label global for linker
_main:
    cmp 4, 5 ; Compare 4 and 5
    je _equal ; je = jump if equal
    jl _less ; jl = jump if less
    jg _greater ; jg = jump if greater
exit:
    ret ; Return
_equal:
    ; Whatever code here
    mov rax, 0x2000004 ; sys_write, 4 for linux
    mov rdi, 1 ; STDOUT
    mov rsi, msg_eq
    mov rdi, len_eq
    
    syscall
    
    jmp exit ; Exit
_less:
    ; Whatever code here
    mov rax, 0x2000004
    mov rdi, 1
    mov rsi, msg_le
    mov rdi, len_le
    
    syscall
    
    jmp exit
_greater:
    ; Whatever code here
    
    mov rax, 0x2000004
    mov rdi, 1
    mov rsi, msg_gr
    mov rdi, len_gr
    
    syscall
    jmp exit

Intel構文アセンブリで条件が真である間にループする

section .data
    msg db 'Hello, world!', 0xA
    len equ $ - msg
section .text
global _main
_main:
    mov rax, 0 ; This will be the current number
    mov rcx, 10 ; This will be the last number
    
_loop:
    cmp rax, rcx
    jl .loopbody ; Jump to .loopbody if rax < rcx
    jge _exit ; Jump to _exit if rax ≥ rcx
.loopbody:
    push rax ; Store the rax value for later use

    mov rax, 0x2000004 ; 4 for Linux
    mov rdi, 1 ; STDOUT
    mov rsi, msg
    mov rdx, len

    syscall

    pop rax ; Take it back to rax

    inc rax ; Add 1 to rax. This is required since the loop must have an ending.    

    jmp _loop ; Back to loop
_exit:
    ret    ; Return

rax < rcxあれば.loopbodyを実行します。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow