[英]how to test condition properly: je or jge
有時我會使用這種模式來迭代一些數組:
mov [rsp+.r12], r12 ; Choose a register that calls inside the loop won't modify
mov r12, -1
.i:
inc r12
cmp r12, [rbp-.array_size]
je .end_i
; ... program logic ...
jmp .i
.end_i:
mov r12, [rsp+.r12]
我知道測試平等就足夠了,但是不應該對“更大或更平等”進行“安全”測試(防止出現這種情況)。
在這種情況下,應該使用je還是jge?
我問的是可以減少引入錯誤的可能性的具體技巧。
我一直很喜歡測試一個范圍而不是僅僅為了相等的想法,以防萬一意外翻轉或其他原因。 但是在x86 asm中,請記住, cmp/jge
不能在Core2上進行宏 cmp/jge
(在32位模式下),而cmp/je
可以。 在我檢查了Agner Fog的microarch pdf文件並發現只有Core2而不是Nehalem之前,我認為這將更有意義,因為在2004年的64位模式下宏融合根本不起作用,核心2。 (后來的微體系結構沒有該限制,並且可以對越來越多的組合進行宏融合。)
根據計數器的不同,您通常可以完全不使用CMP進行遞減計數(dec / jnz)。 通常,您知道它不需要是64位的,因此可以使用dec esi / jnz
或其他任何方式。 dec esi / jge
可以用於簽名計數器,但是dec
沒有設置CF,因此您不能(有用)使用JA。
您的循環結構中間有一個if() break
,結尾有一個jmp,對於asm來說不是慣用的。 正常情況是:
mov ecx, 100
.loop: ; do{
;; stuff
dec ecx
jge .loop ; }while(--ecx >= 0)
您可以使用jg僅使用正ecx重新啟動循環,即從100..1而不是100..0開始循環。
在循環中具有未采用的條件分支和未采用的無條件分支效率較低。
擴展討論中有關保存/恢復r12的注釋的討論:通常,您會執行以下操作:
my_func:
; push rbp
; mov rbp, rsp ; optional: make a stack frame
push rbx ; save the caller's value so we can use it
sub rsp, 32 ; reserve some space
imul edi, esi, 11 ; calculate something that we want to pass as an arg to foo
mov ebx, edi ; and save it in ebx
call foo
add eax, ebx ; and use value. If we don't need the value in rbx anymore, we can use the register for something else later.
... ;; calculate an array size in ecx
test ecx, ecx ; test for the special case of zero iterations *outside* the loop, instead of adding stuff inside. We can skip some of the loop setup/cleanup as well.
jz .skip_the_loop
; now use rbx as a loop counter
mov ebx, ecx
.loop:
lea edi, [rbx + rbx*4 + 10]
call bar ; bar(5*ebx+10);
; do something with the return value? In real code, you would usually want at least one more call-preserved register, but let's keep the example simple
dec ebx
jnz .loop
.skip_the_loop:
add rsp, 32 ; epilogue
pop rbx
;pop rbp ; pointless to use LEAVE; rsp had to already be pointing to the right place for POP RBX
ret
請注意,我們是如何在功能內使用rbx的,但只保存/恢復一次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.