我想根据寄存器的内容调用过程。该过程完成后,应返回到调用地址,以便程序可以继续执行call
操作码之后的代码,否则应忽略它并继续执行其余代码。
我正在尝试避免像在call subroutines conditionally in assembly上的答案所描述的那样,有条件地跳过call
和jcc
。
有可能吗?像这样:
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
在不使用跳转的情况下如何实现呢?
答案 0 :(得分:4)
我想根据寄存器的内容调用过程。 ...我试图避免在这里使用跳转。可能吗? ... 一个不使用跳转怎么实现呢?
不幸的是,大多数CPU仅对跳转/分支指令支持条件执行。
ARM CPU支持几乎所有指令的条件执行。历史悠久的8080及其兼容版本(8085,Z80)除了跳转之外,还支持有条件地执行CALL
和RET
。
但是,x86 CPU与大多数CPU一样:只能有条件地执行跳转指令。
假设,您可以在RAM中使用自修改代码来有条件地执行任何指令,而无需使用跳转指令。但是,这样做只会对某些可行性研究有用,而对于任何实际用例都不会有用。
答案 1 :(得分:3)
您要在汇编代码中实现if-else结构,如以下C代码所示
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
}
在汇编中,您将通过以下方式编写此代码:
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
这是在汇编中编写if-else块的两种经典方法之一(推理是相同的,只是指令有所更改)。另一个选择是将else-branch代码放在if-branch之前,以进行更具逻辑性的条件跳转(因为在第一个示例中,我们测试相等性,但是如果不相等则跳转)。使用第二个选项,汇编代码将为
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
在您的情况下,由于没有其他分支,因此首选第一个选项(因为无需跳转到elseBranch
标签(并且不需要第二个{{1} })。
对于您的代码,最终答案将是:
endIf