수색…


소개

모든 사소한 소프트웨어는 조건에 따라 프로그램 흐름을 전환하기 위해 흐름 제어 구조가 필요합니다. 가장 낮은 레벨의 프로그래밍 언어 인 어셈블리는 제어 구조에 대한 프리미티브 만을 제공합니다. 일반적으로 기계 작동은 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에는 루프 카운트를 구현하는 특정 명령이 있습니다. "감소 B 레지스터와 점프가 0이 아닌 경우 점프"를 DJNZ 입니다. 따라서 B는이 프로세서에서 루프를 구현하기 위해 선택한 레지스터입니다. FOR ... NEXT는 "거꾸로"구현되어야하는데, 그 이유는 레지스터가 0으로 계산되기 때문입니다. 8086과 같은 다른 CPU (이 CPU는 루프 카운터로 CX 레지스터를 사용함)는 비슷한 특정 루프 카운터 레지스터 및 명령어를 가질 수 있습니다. 일부 다른 CPU는 임의 레지스터 (m68k에는 모든 데이터 레지스터에서 작동하는 DBRA 명령어가 있음)로 루프 명령을 허용합니다.

; 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 를 실행 rax < rcx .



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow