相关疑难解决方法(0)

为什么循环总是被编译成"do ... while"样式(尾部跳转)?

当试图理解汇编(启用编译器优化)时,我看到这种行为:

这样一个非常基本的循环

outside_loop;
while (condition) {
     statements;
}
Run Code Online (Sandbox Code Playgroud)

经常被编译成(伪代码)

    ; outside_loop
    jmp loop_condition    ; unconditional
loop_start:
    loop_statements
loop_condition:
    condition_check
    jmp_if_true loop_start
    ; outside_loop
Run Code Online (Sandbox Code Playgroud)

但是,如果未打开优化,则会编译为通常可理解的代码:

loop_condition:
    condition_check
    jmp_if_false loop_end
    loop_statements
    jmp loop_condition  ; unconditional
loop_end:
Run Code Online (Sandbox Code Playgroud)

根据我的理解,编译后的代码更像是这样的:

goto condition;
do {
    statements;
    condition:
}
while (condition_check);
Run Code Online (Sandbox Code Playgroud)

我看不到巨大的性能提升或代码可读性提升,为什么经常出现这种情况呢?是否有此循环样式的名称,例如"尾随条件检查"?

optimization performance assembly loops micro-optimization

26
推荐指数
1
解决办法
1675
查看次数

如何阅读英特尔操作码表示法

我正在阅读一些关于英特尔操作码汇编指令的资料,但我无法理解它遵循操作码字节是什么意思.例如:"cw","cd","/ 2","cp","/ 3".请给我一个提示是什么意思或在哪里可以找到完整的参考?提前致谢!

E8 cw CALL rel16相对于下一条指令调用near,relative,displacement

E8 cd CALL rel32相对于下一条指令调用near,relative,displacement

FF / 2 CALL r/m16调用r/m16中给出的接近绝对间接地址

FF / 2 CALL r/m32调用r/m32中给出的接近绝对间接地址

9A cd CALL ptr16:16调用操作数中给出的far,absolute,address

9A cp CALL ptr16:32调用操作数中给出的far,absolute,address

FF / 3 CALL m16:16调用m16:16中给出的远,绝对间接地址

FF / 3 CALL m16:32调用m16:32中给出的远,绝对间接地址

x86 assembly intel machine-code opcode

15
推荐指数
3
解决办法
4909
查看次数

$ NAS如何在NASM中工作?

message db "Enter a digit ", 0xA,0xD
Length equ $- message
Run Code Online (Sandbox Code Playgroud)

它用于获取字符串的长度吗?
它在内部如何运作?

x86 assembly nasm

4
推荐指数
1
解决办法
1833
查看次数

rbp不允许作为SIB基础?

我对x86-64二进制编码很新.我正在尝试修复一些旧的"汇编程序"代码.

无论如何,我正在尝试做这样的事情(英特尔语法):

mov    [rbp+rcx], al
Run Code Online (Sandbox Code Playgroud)

汇编程序目前正在生成:

88 04 0D
Run Code Online (Sandbox Code Playgroud)

但这似乎不是一个有效的指示.如果我将SIB字节中的基数更改rbp为其他寄存器,则可以正常工作.另一种使其工作的方法是添加一个零字节的位移(88 44 0D 00).这似乎与其他类似的操作码一起发生.

为什么我不能rbp在那里使用mod=00

x86 assembly x86-64 machine-code addressing-mode

1
推荐指数
1
解决办法
178
查看次数