Compiler construction 条件跳转指令?

Compiler construction 条件跳转指令?,compiler-construction,cpu,Compiler Construction,Cpu,完成编译器设计课程: 什么是条件跳转指令?我是基于C/C++的程序员,所以如果在这个范例中有任何代码示例,您可以与我分享,以帮助我更好地理解这一点 无限条件跳转指令是什么意思 书中的一个语句示例: 许多处理器都有条件跳转 仅适用于有条件 在有限的范围内跳跃。对于 例如,跳转的目标可能是 距离不超过128字节 从当前程序计数器。 有时,一个汇编程序为这样一个 处理器仍然允许无限的 条件跳转 我需要了解汇编程序才能理解这一点吗 我希望能链接到参考资料以供进一步阅读。关于条件分支,您可以从以下定义开始

完成编译器设计课程:

什么是条件跳转指令?我是基于C/C++的程序员,所以如果在这个范例中有任何代码示例,您可以与我分享,以帮助我更好地理解这一点

无限条件跳转指令是什么意思

书中的一个语句示例:

许多处理器都有条件跳转 仅适用于有条件 在有限的范围内跳跃。对于 例如,跳转的目标可能是 距离不超过128字节 从当前程序计数器。 有时,一个汇编程序为这样一个 处理器仍然允许无限的 条件跳转

我需要了解汇编程序才能理解这一点吗


我希望能链接到参考资料以供进一步阅读。

关于条件分支,您可以从以下定义开始:

:

有两种常见的分支形式 指令:一个条件分支,它 可以采取或不采取, 取决于诸如CPU之类的条件 标志,以及无条件分支 这是经常发生的事

if、for、while C语句编译为条件跳转汇编运算符。而goto语句则编译为无条件跳转运算符

关于跳转的有限/无限范围:范围是内存中跳转指令地址和跳转到的地址之间的距离。维基百科上的这篇文章可以给你更多关于这件事的信息

为了理解这些主题,您不必了解汇编程序编程,但我建议您学习CPU体系结构的基础知识。

关于条件分支,您可以从以下定义开始:

:

有两种常见的分支形式 指令:一个条件分支,它 可以采取或不采取, 取决于诸如CPU之类的条件 标志,以及无条件分支 这是经常发生的事

if、for、while C语句编译为条件跳转汇编运算符。而goto语句则编译为无条件跳转运算符

关于跳转的有限/无限范围:范围是内存中跳转指令地址和跳转到的地址之间的距离。维基百科上的这篇文章可以给你更多关于这件事的信息

为了理解这些主题,您不必了解汇编程序编程,但我建议您学习CPU体系结构的基础知识。

简而言之:

条件的意思是

if(condition)
{
  //condition met
}
else
{
  //condition no met
}
这意味着程序流根据条件表达式而改变

无条件跳转是goto语句或函数调用的典型编译器实现。

简而言之:

条件的意思是

if(condition)
{
  //condition met
}
else
{
  //condition no met
}
这意味着程序流根据条件表达式而改变


无条件跳转是goto语句或函数调用的典型编译器实现

if (condition) goto
goto
在C中,无条件跳转就像

if (condition) goto
goto
在C


我不知道无限意味着什么。它可能特定于讨论中的特定处理器。

条件跳转类似于

if (condition) goto
goto
在C中,无条件跳转就像

if (condition) goto
goto
在C


我不知道无限意味着什么。它可能特定于讨论中的特定处理器。

条件跳转逻辑上会将此if语句转换为:

if(a == b)
{
  // do something
}

// do something else
为此:

if(!(a==b)) goto somethingElse;
// do something

somethingElse:
// do something else
如果!然后,a==b行将转换为汇编命令:

CMP A, B
JNE somethingElse

现在,对于无限条件跳转,我假设它们是指远跳转?

条件跳转在逻辑上会使if语句:

if(a == b)
{
  // do something
}

// do something else
为此:

if(!(a==b)) goto somethingElse;
// do something

somethingElse:
// do something else
如果!然后,a==b行将转换为汇编命令:

CMP A, B
JNE somethingElse

现在,关于无限条件跳转,我假设它们是指远跳转?

我认为这解决了您的问题:例如,在Microchip PIC18F系列中,您有一个bra分支命令和一个goto命令。它们实际上是相同的,但区别在于bra命令只能从其位置跳转到-1024到+1023个字的位置,并且只使用一个字的程序内存。goto命令可以在程序内存中的任何位置跳转,但它需要两个字的程序内存才能允许跳转到任何位置

如果您错误地尝试分支到太远的标签,编译器将给您一个错误

当然,当你只有,比如说,2K个字的程序内存时,这些额外的字会产生不同

bra和goto本身就是无条件的跳跃;但是,有几个条件分支命令,例如bc-branch if-carry、bz-branch if-zero、bnz-branch if-not-zero等,所有这些命令都检查上一次算术运算的状态寄存器,并且仅在指定条件为真时执行分支

如果你需要有条件的转到,那么你会有一些 诸如此类

DELAY
    nop
    nop
    decfsnz DelayCount
    goto DONE_WITH_DELAY
    bra DELAY

在那里,我们执行两次“不行动”来睡一会儿;递减一个名为DelayCount的变量,如果DelayCount为零,则无条件跳转到标有DONE_的代码,并使用_DELAY;如果它不是零,我们跳回到延迟标签,然后再做一次。decfsnz的意思是减量f,如果不是零则跳过

我想这解决了你的问题:例如,在微芯片PIC18F系列中,你有一个bra分支命令和一个goto命令。它们实际上是相同的,但区别在于bra命令只能从其位置跳转到-1024到+1023个字的位置,并且只使用一个字的程序内存。goto命令可以在程序内存中的任何位置跳转,但它需要两个字的程序内存才能允许跳转到任何位置

如果您错误地尝试分支到太远的标签,编译器将给您一个错误

当然,当你只有,比如说,2K个字的程序内存时,这些额外的字会产生不同

bra和goto本身就是无条件的跳跃;但是,有几个条件分支命令,例如bc-branch if-carry、bz-branch if-zero、bnz-branch if-not-zero等,所有这些命令都检查上一次算术运算的状态寄存器,并且仅在指定条件为真时执行分支

如果你需要一个有条件的转到,那么你会有

DELAY
    nop
    nop
    decfsnz DelayCount
    goto DONE_WITH_DELAY
    bra DELAY
在那里,我们执行两次“不行动”来睡一会儿;递减一个名为DelayCount的变量,如果DelayCount为零,则无条件跳转到标有DONE_的代码,并使用_DELAY;如果它不是零,我们跳回到延迟标签,然后再做一次。decfsnz表示减量f,如果不是零则跳过

许多处理器只有有限范围的条件跳转指令。例如,跳转目标与当前程序计数器的距离可能不超过128字节

以一个x86条件跳转(如JNZ)为例,这意味着如果处理器的零标志未设置,则跳转将由先前的算术运算设置或清除

JNZ操作码有一个表示跳转距离的操作数。对于JNZ操作码,操作数使用单字节编码,即仅将操作码后的第一个字节解释为操作数;下一个字节是下一个操作码的开始,因此它可以指定不超过正负128字节的跳转

[它使用一个短的1字节操作数,因为短跳转是最常见的情况,对最常见情况的优化有助于使整个代码更小]

有时,这种处理器的汇编程序仍然允许无限的条件跳转

这意味着当您在高级程序集中写入时,您可以写入

jnz distant_label
[other instructions]
distant_label:
。。。即使距离标签超过128字节。当CPU本身只支持短条件跳转时,它如何做到这一点?可能是因为“汇编”你的汇编语言的汇编器,像编译器一样,自动插入一些额外的必要的操作码,所以实际上最终发出的是

jz nearby_label
jmp distant_label
nearby_label:
[other instructions]
distant_label:
。。。其中:

jmp是一个无条件跳转,它有一个更大的操作数,可以无限跳转 代替jnz远处的标签,这里有jz近处的标签-'jnz'被'jz'替换,这意味着如果标志不是零,它不会跳转到远处的标签,它会跳转到附近的标签,所以不要跳远,如果标志是零,这意味着与您所写的内容相同,因为如果不是零跳和如果零不跳的意思是一样的。 许多处理器只有有限范围的条件跳转指令。例如,跳转目标与当前程序计数器的距离可能不超过128字节

以一个x86条件跳转(如JNZ)为例,这意味着如果处理器的零标志未设置,则跳转将由先前的算术运算设置或清除

JNZ操作码有一个表示跳转距离的操作数。对于JNZ操作码,操作数使用单字节编码,即仅将操作码后的第一个字节解释为操作数;下一个字节是下一个操作码的开始,因此它可以指定不超过正负128字节的跳转

[它使用一个短的1字节操作数,因为短跳转是最常见的情况,对最常见情况的优化有助于使整个代码更小]

有时,这种处理器的汇编程序仍然允许无限的条件跳转

这意味着当您在高级程序集中写入时,您可以写入

jnz distant_label
[other instructions]
distant_label:
。。。即使距离标签超过128字节。当CPU本身只支持短条件跳转时,它如何做到这一点?可能是因为“汇编”你的汇编语言的汇编器,像编译器一样,会自动插入一些额外必要的操作码,所以 事实上,t最终会被释放出来,就像

jz nearby_label
jmp distant_label
nearby_label:
[other instructions]
distant_label:
。。。其中:

jmp是一个无条件跳转,它有一个更大的操作数,可以无限跳转 代替jnz远处的标签,这里有jz近处的标签-'jnz'被'jz'替换,这意味着如果标志不是零,它不会跳转到远处的标签,它会跳转到附近的标签,所以不要跳远,如果标志是零,这意味着与您所写的内容相同,因为如果不是零跳和如果零不跳的意思是一样的。
对不起,我的意思是说,是的,我设法收集了IA-32的全部三卷作品——sorta援引了之前在公开论坛上回答第一天问题所造成的不妥协战争的伤痕。我们可以推荐HP手持计算器作为更好的初学者场所吗?这很好地回答了op最初的问题。试图让op在8位微型计算机中实现有限自动机。我是不是被扭曲了?对不起,我的意思是说,是的,我设法收集了IA-32的全部三卷作品——sorta援引了之前在公开论坛上回答第一天问题所造成的不妥协战争的伤痕。我们可以推荐HP手持计算器作为更好的初学者场所吗?这很好地回答了op最初的问题。试图让op在8位微型计算机中实现有限自动机。我是不是被扭曲了-1这个答案毫无意义。有条件的跳转不会把任何东西变成任何东西。-1这个答案毫无意义。条件跳转不会将任何东西转换成任何其他东西。我想说,至少掌握基本汇编语言的知识是编译器设计课程的先决条件。我并不是说这有点刺耳,只是说你们需要在学习汇编语言上付出一些努力。我希望能链接到参考资料以供进一步阅读。谷歌递归下降分析器,保存残酷的asm的东西后,几天的工作。Google q=只筛选那些看起来像编译器的响应。谷歌:大卫·埃基(David EckI)会说,至少掌握基本汇编语言是编译器设计课程的先决条件。我并不是说这有点刺耳,只是说你们需要在学习汇编语言上付出一些努力。我希望能链接到参考资料以供进一步阅读。谷歌递归下降分析器,保存残酷的asm的东西后,几天的工作。Google q=只筛选那些看起来像编译器的响应。谷歌:大卫·埃基对优化很感兴趣。读完这篇文章后,我想知道跳跃的距离会在多大程度上影响速度。我对优化感兴趣。读完这篇文章后,我想知道跳跃的距离会在多大程度上影响速度。