I want to call a procedure depending on the contents of a register. After the procedure has finished it should return to the calling address so that the program can keep executing the code following the call
opcode, otherwise it should ignore it and keep executing the rest of the code.
I'm trying to avoid just conditionally jumping over the call
with a jcc
, like the answers on call subroutines conditionally in assembly describe.
Is it possible? Something like this:
cmp al,41h ;check if register has value 41h
call setAsize ;call procedure if it does, otherwise ignore and continue executing code
//more code to execute here
setASize:
mov al,4d ;change register content
ret ;return to call address so that code following call opcode can continue being executed
How would one implement this without using a jump?
You want to implement a if-else structure in your assembly code as in the following C-code
if (al == 0x41) { // we keep your example values
// do something
setASize();
} else {
// do something else
// not present in your code but there for the sake of completeness
}
In assembly, you will write this the following way:
cmp al, h41 ; this is the comparison, which sets flags
jne elseBranch ; if the zero flag is *not* set (al != h41) jump to elseBranch
; the jne instruction can be replaced with any other conditional
; jump to adjust to the test condition
ifBranch: ; useless label for clarity
call setASize ; this is the actual if-code (do-something)
jmp endIf ; now jump to the end of the if to avoid the else-branch
elseBranch:
; nothing in your code, but this is where you put
; your else instructions
endIf:
; now is the code after your if-else block, which will be executed in any case
This is the one of the two classic ways to write a if-else block in assembly (the reasonning is the same only the instructions change). The other option is to put the else-branch code before the if-branch to have the more logical conditional jump (since in the first example we test equality but jump if not equal). With this second option, the assembly code would be
cmp al, h41 ; this is the comparison, which sets flags
je ifBranch ; if the zero flag is *not* set (al != h41) jump to elseBranch
; the jne instruction can be replaced with any other conditional
; jump to adjust to the test condition
elseBranch: ; useless label for clarity
; nothing in your code, but this is where you put
; your else instructions
jmp endIf ; now jump to the end of the if to avoid the else-branch
ifBranch:
call setASize ; this is the actual if-code (do-something)
endIf:
; now is the code after your if-else block, which will be executed in any case
In your case, since there is no else branch, the first option is prefered (only one jump required since you do not need to jump to the elseBranch
labels (and do not need the second endIf
jump).
For you code, the final answer would be:
cmp al,41h
jne endIf
call setAsize
endIf:
; more code here
setASize:
mov al,4d
ret