【问题标题】:Go back after jump跳跃后返回
【发布时间】:2020-08-04 15:48:54
【问题描述】:

我有这个代码,我需要检查RCX 注册三遍。我做了几行代码(24-34行)。第一次(第一次jz),我移动到true:标签,但是第二次(28-30行)我不能回去检查它。我的程序每次都在第一个jz 之后完成。怎么回去查三遍?

default REL
extern GetStdHandle
extern WriteFile
extern ExitProcess


section .data
    true_msg db 'Yes', 0

    true_msg_len equ $-true_msg

section .text
    global _main

_main:
    and rsp, -10h
    sub rsp, 020h

    mov rcx, -0Bh
    call GetStdHandle

    ;jmp true

    mov rcx, 2
    cmp rcx, 2
    jz true

    mov rcx, 0
    cmp rcx, 0
    jz true
    
    mov rcx, 1
    cmp rcx, 0
    jz true

;----------------
    add rsp, 28h                            ; Restore Stack Pointer
;----------------
    mov rcx, 0                              ; RCX - first argument.
    call ExitProcess
;----------------
    xor rax, rax
    ret

true:
    mov rcx, rax
    mov rdx, true_msg
    mov r8, true_msg_len
    xor r9, r9
    push r9
    sub rsp, 20h
    call WriteFile

我想得到类似的东西:

if(...){
   ...
}

if(...){
   ...
}

if(...){
   ...
}

我需要检查每个条件。

【问题讨论】:

  • 为什么在每种情况下都跳到true?是否总是应该执行相同的代码?如果是这样,为什么不写成if (cond1 || cond2 || cond3) { ... }呢?
  • 如果它 not 总是应该执行相同的代码,那么明显的解决方案是执行类似jnz @F 之类的操作,然后执行应该执行的代码 (或 call 指向包含该代码的函数)后跟 @@:。如果您更喜欢命名标签而不是匿名标签,那很好。
  • @Michael:这看起来像 NASM 源。 NASM 没有内置@@ 样式标签。(但是,my macro collection 可以添加对@@ 的支持,包括multi-step references。)

标签: if-statement assembly label x86-64 nasm


【解决方案1】:

对如何执行此操作存在误解。简单来说:

if (test) {
   //block1
}
if (test2) {
   //block2
}
if(test3) {
   //block3
}

(注意那些block1,block2和block3将出现在我的下一个例子中)

每个 if 都需要测试(括号中的测试),然后去执行它是真的可能性和不正确的可能性。 所以它会是这样的:

;first if, start by comparing:
   mov rcx, 2
   cmp rcx, 2
   jnz false1 ;jumps for the false possibility of the first if

   ;here you type what will happen when the first if is executed (block1)

false1: ;here the first if is finnished, this label is the jump for not executing that first if

   ;then now you execute the second if:

   ;first compare:
   mov rcx, 0
   cmp rcx, 0
   jnz false2 ;jumps for not executing the if block

   ;here is block2

false2:

   ;now here the last if, just like the last two:

   mov rcx, 1
   cmp rcx, 0
   jnz false3

   ;here block3

false3:
   ;here is the rest of your code after those ifs

我更改了跳入错误可能性而不是正确的逻辑(就像您所做的那样),因为在没有“else”块的情况下,它会使代码比您做的更小。

【讨论】:

  • 是的,当 if 块不应该被执行时,你经常想要跳过一个块。为了保持与问题中的代码相同的条件,您应该使用相反的条件jnz(或者在cmpjne 之后更惯用)。即将if(test) stuff; 变成if(!test) goto after_stuff;。所以 if 主体在 2 == 2 时执行。
  • 对了,我忘记把jz转成jnz了,我用正确的跳转编辑了答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-16
相关资源
最近更新 更多