首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理器如何处理条件?

处理器如何处理条件?
EN

Stack Overflow用户
提问于 2009-03-25 19:42:41
回答 7查看 2.6K关注 0票数 5

那么,超低级的IF()是什么样子的,x86处理器是如何处理它的?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-03-25 19:45:29

处理器有"Branch if“指令,当满足某个条件时,它会进行分支,否则它会继续执行下一条指令。

所以

代码语言:javascript
复制
if(A)
{
    dosomething;
}

会变成

代码语言:javascript
复制
load A into register 0
if the zero flag is set (ie, register 0 contains 0x00) then jump to endcondition)
dosomething
endcondition:

更复杂的条件( if(A || B && C) )成为使寄存器处于0或非零状态的指令序列,因此分支指令可以根据条件标志跳转或不跳转。

有许多条件标志(零、进位、负、溢出等),一些分支指令也在更复杂的条件下操作(例如,它实际上可能会检查一个寄存器是否等于另一个寄存器,而不是简单地查看标志)。每种体系结构都是不同的,并进行权衡,因此指令集是完整的,但也是快速和紧凑的。

正如moocha在评论中指出的那样,一些架构允许你对一些、许多甚至所有指令应用条件,因此你可能不仅有“分支if”指令,还有“and if”、“add if”、“move if”等指令。

一旦涉及到流水线、乱序执行、缓存、微代码和所有其他高级主题,除了这个简单的解释之外,x86非常非常复杂。对于大多数目的,上述解释就足够了。但是,如果您正在编写一个手工制作的非常非常紧密的算法,则必须考虑这些因素,以获得最大的性能和吞吐量。

不过,这是另一个问题的主题。

-Adam

票数 13
EN

Stack Overflow用户

发布于 2009-03-25 20:03:01

使用C编译器的输出非常容易(使用-S开关打开gcc)来查看给定的C代码片段在编译时将生成什么输出。不过,在玩具程序上使用优化时要小心。如果您不小心,优化器通常会优化掉总会以某种方式出现的条件条件(有关更详细的解释,请参阅this article on microbenchmarks )。

例如,一个简单的C程序:

代码语言:javascript
复制
#include <stdio.h>

int main (int argc, char **argv) {
    int ii = 10;
    int jj = 20;
    if (jj > ii) {
        puts ("jj > ii \n");
    }
    return 0;
}

编译为以下汇编语言:

代码语言:javascript
复制
    .file   "foo.c"
    .section    .rodata
.LC0:
    .string "jj > ii \n"
    .text
.globl main
    .type   main, @function
main:
    leal    4(%esp), %ecx
    andl    $-16, %esp
    pushl   -4(%ecx)
    pushl   %ebp
    movl    %esp, %ebp
    pushl   %ecx
    subl    $20, %esp
    movl    $10, -8(%ebp)
    movl    $20, -12(%ebp)
    movl    -12(%ebp), %eax
    cmpl    -8(%ebp), %eax
    jle .L2
    movl    $.LC0, (%esp)
    call    puts
.L2:
    movl    $0, %eax
    addl    $20, %esp
    popl    %ecx
    popl    %ebp
    leal    -4(%ecx), %esp
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.3.2-1ubuntu12) 4.3.2"
    .section    .note.GNU-stack,"",@progbits

对于正在发生的事情的简要剖析:

第一部分(.rodata)使用字符串声明一个常量,第二部分正在初始化堆栈上iijj变量的内容。

  • cmpl -8(%ebp), %eax中的位进行实际比较;jle指令跳过对'puts‘的调用,这实际上是'if’语句的逻辑颠倒。

  • 在标签'.L2‘之后,系统正在整理堆栈顶部并从调用中返回。
票数 5
EN

Stack Overflow用户

发布于 2009-03-25 19:49:37

它是一个分支指令,依赖于特定的机器架构。它找出如何设置内存位置或寄存器来测试特定的低级条件-如分支-如果不等于或分支-如果不是零,... -执行该测试,然后跳转(或如果条件失败则不跳转)到内存的另一部分。显然,如果你有一个复杂的条件,它可能需要计算许多不同的条件,并可能涉及几个分支指令。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/683126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档