Assembly Language
Controllo del flusso
Ricerca…
introduzione
Trivial IF-THEN-ELSE in m68k Assembly
; 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
Quali istruzioni influenzano quali flag e quali rami condizionali (che potrebbero anche essere basati su specifiche combinazioni di flag ) sono disponibili, dipende molto dalla CPU scelta e dovrebbe essere consultata nei manuali.
FOR ... NEXT in Z80 Assembly
Lo Z80 ha un'istruzione specifica per implementare i conteggi di loop: DJNZ
sta per "decrement B register e jump if not zero". Quindi, B è il registro di scelta per implementare i loop su questo processore. FOR ... NEXT deve essere implementato "all'indietro", perché il registro conta fino a zero. Altre CPU (come l'8086, questa CPU utilizza il registro CX come contatore di loop) potrebbero avere registri e istruzioni del contatore di loop specifici simili, alcune altre CPU consentono comandi di loop con registri arbitrari (m68k ha un'istruzione DBRA che funziona con qualsiasi registro dati).
; 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
Istruzione if in assembly Intel-syntax
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
Loop while condition è vero nell'assembly della sintassi 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
Questo eseguirà .loopbody
fintanto che rax < rcx
.