问题描述
我正在尝试制作一个使程序具有“电传书效果”的程序,以打印在r0中由参数传递的字符串,一个字符接一个字符,在上一个和下一个打印之间间隔一段时间。 该程序可以运行,但是会发生一些奇怪的事情。 r2寄存器包含“ time-loser”值。从理论上讲,最大值是该值,“ lose_time”子例程必须执行的循环越多,因此每个字符打印之间的时间就越多。但是实际上,即使我将r2值更改为非常高的值,也不会改变任何值。为什么?
电话:
.global tele
.type tele%function
@ r0 = array
@ r1 = signle char
@ r2 = time-loser
tele:
mov r2,#700 // if I edit this,it doesn't change anything
push {ip,lr} // save lr
loop:
ldr r1,[r0],#1 // at each loop it increase the array pointer and so r1 takes the next value in the array
cmp r1,#0 // if the value is NULL
beq end // array is ended and returns
push {r0,r2} // save the r0(array address) and r2(my time-loser value)
ldr r0,=message
bl printf // prints one single char
bl lose_time // then lose time
pop {r0,r2} // and take r0,r2 values back
b loop // do the cycle again
lose_time:
sub r2,r2,#1 // sub 1
cmp r2,#0 // until it reaches 0
bxeq lr // if reaches 0,it returns to "loop" subroutine
b lose_time // else do the cycle again
end:
pop {ip,lr} // if the program ends,it takes the lr back
bx lr // and returns
message:
.asciz "%c\n"
奇怪的是,即使我输入了700(非常低的值),打印仍然会延迟。打印起来真的很慢,就像我输入的数字更高时一样。那为什么呢?
main.c:
int tele(char *);
int main(){
char string[] = "Teleprinter effect";
tele(string);
return 0;
}
解决方法
解决了。
我将r2保存到内存中,但仅在调用延迟循环后才将其恢复。
// r2 is 700
bl printf // prints one single char
// r2 is garbage
bl lose_time // then lose time
// r2 is 0
pop {r0,r2} // and take r0,r2 values back
// r2 is 700 again
一个人在这里帮助了我:https://www.reddit.com/r/asm/comments/ir715b/arm_trying_to_reproduce_a_teleprinter_effect_but/