在汇编中跳出 global main 是否仍被视为 main 函数的一部分?
Is jumping out of global main still considered as part of main function, in assembly?
我们通过调用 jmp 访问的部分代码是否仍被视为汇编中主函数的一部分?
示例:
main:
mov ebx,3
push ebx
jmp for_loop ; this part
rec:
;some function
for_loop:
;logic
je exit
call rec
;logic
jmp for_loop
exit:
pop ebx
mov eax,0
ret
不使用 jmp 并在 main
下写 for_loop
会更好吗?
嗯,看起来有点乱。
汇编中没有main函数。您可以将执行开始的入口点称为 "main",但事实就是如此。这只是机器代码中不存在的虚构标签。函数可以是您 call
的任何内容,因为处理器的 call
指令在他 jmp
执行时会进行一些设置,但仅此而已。
就个人而言,我会对其进行相当多的重组。
main:
xor ebx,ebx
add ebx,3 ; saves a byte
push ebx
forloop:
; I assume here you do a dec, or cmp, for the following:
je exit
; put the code for "rec" in here.
; No point wasting the bytes and time to jump.
jmp forloop
exit:
pop ebx
xor eax,eax
ret
好的,所以这仍然是一团糟,但我对你想要实现的目标的了解存在漏洞。
开头的 je exit
可能连接到应该在其之前的 "logic"。我个人宁愿尝试解读它,扭转它。这意味着,假设 "logic" 允许我这样做,我会把它变成 jne forloop
并将其放在循环的末尾,这样我就可以避免 jmp 到开头。还可以再次为您节省几个字节。
xor eax,eax
是一种更短、更快捷的将寄存器设置为零的方法。如果你真的 需要 rec
成为一个单独的函数,那么至少把它放在这个块之外,这样你就不必使用 jmp for_loop
跳过它.您可以放心地将它放在 ret
.
之后
整部:
rec:
; some function (ending with ret?!)
可以移到代码 exit:
部分的 ret
之后,然后你将 "main" 放在一起, "rec" 分开,如下所示:
main:
; some init
; some loop doing "call rec"
; something something
ret
rec:
; some "function" code
ret
然后,到CPU根本无关紧要,它不知道源代码中指令的逻辑分组是什么,或者是否它在一些 "function" 和 "how deep".
里面
CPU 有 cs:eip
地址指针,它将从那里获取并执行下一条指令。这就是它在特定执行时刻所知道的一切。
jmp
指令加载eip
其他地址,然后执行下一条指令。
"subroutines"机制的工作原理是将return地址存储到堆栈内存中,然后通过ret
指令将其加载回eip
,但是如果您调整堆栈内容通过其他方式包含无效的 return 地址,或不同的地址,ret
将崩溃或 "jump" 到其他地址,CPU 不知道它是 "inside" 一些子程序,也不需要 "return" 出来。所有这些都是程序员编写的高级语义逻辑,负责正确设计执行路径,以形成像 "calls of subroutines" 或 "main loops".
这样的逻辑模式
CPU只有cs:eip
和其他寄存器的内容和内存的内容,没有别的。无论指令执行之前的状态是什么,它都确定性地将接下来要执行的指令以及它将产生的影响强加给 CPU 寄存器和计算机内存(以及其他连接的芯片,或者通过 I/O 总线或使用内存的某些部分作为 "mapped" I/O 控制机制)。
所以换句话说,写你的源代码很容易"reading",不要犹豫,花更多的时间写easier/leaner源代码,因为你会READ 比 WRITING 源代码多很多倍(调试、修改)。因此,在您的示例中,将 "rec" 部分代码移出更有意义,而不是交错 "main code" 的 main-loop-ret 链。它应该在源代码级别上阅读得更好。
Is part of the code, which we access with calling jmp, still considered part of main function in assembly?
取决于来源的reader,她是否认为它是主要内容的一部分。机器不关心也不理解这种指令分组的概念。
我们通过调用 jmp 访问的部分代码是否仍被视为汇编中主函数的一部分?
示例:
main:
mov ebx,3
push ebx
jmp for_loop ; this part
rec:
;some function
for_loop:
;logic
je exit
call rec
;logic
jmp for_loop
exit:
pop ebx
mov eax,0
ret
不使用 jmp 并在 main
下写 for_loop
会更好吗?
嗯,看起来有点乱。
汇编中没有main函数。您可以将执行开始的入口点称为 "main",但事实就是如此。这只是机器代码中不存在的虚构标签。函数可以是您 call
的任何内容,因为处理器的 call
指令在他 jmp
执行时会进行一些设置,但仅此而已。
就个人而言,我会对其进行相当多的重组。
main:
xor ebx,ebx
add ebx,3 ; saves a byte
push ebx
forloop:
; I assume here you do a dec, or cmp, for the following:
je exit
; put the code for "rec" in here.
; No point wasting the bytes and time to jump.
jmp forloop
exit:
pop ebx
xor eax,eax
ret
好的,所以这仍然是一团糟,但我对你想要实现的目标的了解存在漏洞。
开头的 je exit
可能连接到应该在其之前的 "logic"。我个人宁愿尝试解读它,扭转它。这意味着,假设 "logic" 允许我这样做,我会把它变成 jne forloop
并将其放在循环的末尾,这样我就可以避免 jmp 到开头。还可以再次为您节省几个字节。
xor eax,eax
是一种更短、更快捷的将寄存器设置为零的方法。如果你真的 需要 rec
成为一个单独的函数,那么至少把它放在这个块之外,这样你就不必使用 jmp for_loop
跳过它.您可以放心地将它放在 ret
.
整部:
rec:
; some function (ending with ret?!)
可以移到代码 exit:
部分的 ret
之后,然后你将 "main" 放在一起, "rec" 分开,如下所示:
main:
; some init
; some loop doing "call rec"
; something something
ret
rec:
; some "function" code
ret
然后,到CPU根本无关紧要,它不知道源代码中指令的逻辑分组是什么,或者是否它在一些 "function" 和 "how deep".
里面CPU 有 cs:eip
地址指针,它将从那里获取并执行下一条指令。这就是它在特定执行时刻所知道的一切。
jmp
指令加载eip
其他地址,然后执行下一条指令。
"subroutines"机制的工作原理是将return地址存储到堆栈内存中,然后通过ret
指令将其加载回eip
,但是如果您调整堆栈内容通过其他方式包含无效的 return 地址,或不同的地址,ret
将崩溃或 "jump" 到其他地址,CPU 不知道它是 "inside" 一些子程序,也不需要 "return" 出来。所有这些都是程序员编写的高级语义逻辑,负责正确设计执行路径,以形成像 "calls of subroutines" 或 "main loops".
CPU只有cs:eip
和其他寄存器的内容和内存的内容,没有别的。无论指令执行之前的状态是什么,它都确定性地将接下来要执行的指令以及它将产生的影响强加给 CPU 寄存器和计算机内存(以及其他连接的芯片,或者通过 I/O 总线或使用内存的某些部分作为 "mapped" I/O 控制机制)。
所以换句话说,写你的源代码很容易"reading",不要犹豫,花更多的时间写easier/leaner源代码,因为你会READ 比 WRITING 源代码多很多倍(调试、修改)。因此,在您的示例中,将 "rec" 部分代码移出更有意义,而不是交错 "main code" 的 main-loop-ret 链。它应该在源代码级别上阅读得更好。
Is part of the code, which we access with calling jmp, still considered part of main function in assembly?
取决于来源的reader,她是否认为它是主要内容的一部分。机器不关心也不理解这种指令分组的概念。