回复 Rainyboy 的帖子
嗯嗯,有空我也试一试。。。
另外,这行代码:printf("%d\n", N - (N - *funcp) * (2*(*funcp < N) - 1));//执行打印写得也很是精妙,深得C语言的精髓啊。 回复 Rainyboy 的帖子
嗯嗯。。。对。。。
当时写的时候是想控制i的输出,i<N时候输出i,i>N时候输出2N-i。
a-b=i
a+b=2N-i
正负号好控制,对比i和N正好控制。然后用i<2N控制范围,后来发现控制范围还是大,,就改用i<2N-i_控制了,i_表示i的初始值,没删除i<2N。:@P
再写一下适用范围:
1、i的范围是MIN_SHORTD到MAX_SHORT,因为i被拆成高二字节和低二字节,同理N也被i限制,尽管N的高位并没有用到。
2、调用约定是_cdecl,相似调用约定也可以,原理见10楼。
3、32位机器。
4、call指令占5个Bytes。(不熟悉AT&T汇编,也不知道AT&T的call占几个Bytes,Masm一般都占5个Bytes或者6个Bytes)
缺陷:如有这样的调用p(-7, -3);还是有问题,考虑再改进一下。
最后感谢版主修正,嘿嘿,没事常交流。。。:@) 回复 wqsong 的帖子
总的来说这是一种很C语言的方法,实实在在地满足了所有条件,让人无话可说,受益匪浅。
多年前我曾经有一个用内联汇编的尝试,现在看来,不值一提,不过还是贴上来吧。int p(int i,int N)
{
_asm{
mov ebx,dword ptr
dec i
stt: mov eax,dword ptr
push eax
push offset szFormat
call printf
add esp,8
inci
mov eax ,dword ptr
cmp eax ,i
jnz stt
ste: dec i
mov eax,dword ptr
push eax
push offset szFormat
call printf
add esp,8
cmp ebx,i
jnz ste
}
} 回复 Rainyboy 的帖子
int p(int i,int N)
{
_asm{
mov ebx,dword ptr
mov ecx ,dword ptr
dec i
stt: mov eax,dword ptr
; inci是否应该在这里呢?
push eax
push offset szFormat
call printf
add esp,8
inci
cmp ecx ,i
jnz stt
ste: dec i
mov eax,dword ptr
push eax
push offset szFormat
call printf
add esp,8
cmp ebx,i
jnz ste
}
}嗯嗯,符合规范的。汇编都快忘没了,学习了,嘿嘿。
记得看《C专家编程》里面,一个卡耐基梅隆大学的一个编程竞赛,各种各样的想法,直接修改进程控制块改变运行时间,:lol。。。
有个地方没看明白,第6行,第一个dec i,为了控制输出N一次,但stt循环的inc i又在printf后面,是否应该把inc i提前到push eax前面呢? 本帖最后由 Rainyboy 于 2010-10-20 13:24 编辑
回复 wqsong 的帖子
提到前面和后面没有区别吧,因为压栈的是eax啊。
《C专家编程》是本好书,你说的那个桥段我也很喜欢,呵呵,还有什么混乱码大赛…… 本帖最后由 wqsong 于 2010-10-20 13:33 编辑
回复 Rainyboy 的帖子
噢,是提到moveax, dword ptr 前面。
sst循环前执行了dec i,进入循环后先打印后自加的话,那么如果有这样的调用
p(2, 3)是否就是打印出
1
2
3
2
呢? 回复 wqsong 的帖子
确实哈……这个代码年代有些久远了,而且我现在用VS2010跑它居然报了一堆错……也罢。。。 回复 Rainyboy 的帖子
嗯,重意不重形,学习了:@)。
版主工作了还是在读呢? 回复 wqsong 的帖子
在读呢,要不哪来时间挂着啊,呵呵 回复 Rainyboy 的帖子
噢,嘿嘿,我也是。。。
马上毕业了,正找工作呢。学热能与动力工程,招聘那些人都不需要写程序的,眼看单位过了一个又一个,都不知道该去哪儿了,哈哈。。。唉:dizzy: 回复 25 # wqsong 的帖子
这两天又找工作去了……都没见你来? 回复 26 # Rainyboy 的帖子
{:{01}:}刚回来。。。忙了半个多月,给你招呼里细说啦。。。呵呵
页:
1
[2]