c语言中提供多种循环结构,即do-while while for,汇编中没有响应指令提供这三种循环
但是可以使用条件测试和跳转进行组合起来 以实现上述三种循环效果,
大多数汇编会根据一个循环的do-while来产生代码,但是实际c代码中相对较少用到这种循环,
这时其它的循环会转化为do-while形式,然后在编译为机器代码
do
body-statement
while (test-expr)
do-while循环至少会执行一次body-statement
而当将其翻译成goto语句如下:
loop:
body-statement
t = test-expr;
if ( t )
goto
c代码:完成1到N的累加
int fact_do(int n) { int result = 1; do{ result += n; n = n-1; }while(n > 1) return nresult; }
汇编代码:
movl 8(%ebp), %edx//将n %edx寄存器中 movl $1, %eax//初始result .L2: addl %edx, %eax//相当于result += n subl $1, %edx//n减一 cmpl $1, %edx//测试条件 jg .L2//决定是否退出循环
while循环翻译到汇编上和do-while是很相似的
while的通用形式:
while(test-expr)
body=statement
在执行第一次循环之前对test-expr进行测试
而将while翻译为汇编有很多种方式一种常见的方法使用条件分支进行第一次循环前的条件测试
当通过了第一次条件测试之后相当于进入do-while循环
if(!test-expr)
goto done;
do
body-statement
while(test-expr)
done:
若将其翻译为goto语句代码则与do-while循环相差的仅仅是if处的分支
将上面do-while改为while型循环 这里只贴出汇编代码
movl 8(%ebp), %edx//将n %edx寄存器中 movl $1, %eax//初始result
cmpl $1, %edx//执行do-while前的条件测试
jle .L3//如果第一次执行前的条件测试没有通过将跳过循环(不进入)
.L2: addl %edx, %eax//相当于result += n subl $1, %edx//n减一 cmpl $1, %edx//测试条件 jg .L2//决定是否退出循环
.L3:
for循环
for(init-expr;test-expr;update-expr)
body-statement
c语言标准说明(有一个例外),for循环与下面的while循环代码的行为相同
init-expr;
while(test-expr)
{
body-statement
update-expr; }
综上所述,c语言中三种形式的循环 for while do-while都可以用一种简单的策略来翻译,即产生一个或多个条件分支的代码。
条件转移为循环 翻译成机器代码提供了基本机制
也就是说for循环转化为汇编前经过
for–>whle–>do-while–>goto–>汇编
在c语言中执行continue语句会导致程序跳到当前循环迭代的结尾。这时将for翻译成while需要进行一些改进
而解决方法是使用goto语句跳过while中余下的代码而到达update部分
例如
int sum = 0
int i;
for(i = 0; i< 10; i++)
{
if(i&1)
continue;
sum +=i; }
for更改后的while代码
int sum = 0
int i = 0;
while(i<10)
{
if(i&1)
goto update;//将此处continue更改为goto
sum +=i;
update:
i++ }
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/290282.html