Assembly Language
흐름 제어
수색…
소개
모든 사소한 소프트웨어는 조건에 따라 프로그램 흐름을 전환하기 위해 흐름 제어 구조가 필요합니다. 가장 낮은 레벨의 프로그래밍 언어 인 어셈블리는 제어 구조에 대한 프리미티브 만을 제공합니다. 일반적으로 기계 작동은 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