ohmytime 发表于 2011-3-5 11:33:49

keil有bug吗?我怎么不能单步调试?进来看看!

写了很简单的一个程序,但是查看了反汇编之后,那个函数根本就没有对应的汇编,我设置断点之后,在stepin进去,直接就出来函数了,难道keil有bug?

这是主程序:
void data_tst();

void main()

{
        uint i = 0;
        i = sizeof(uint);
        data_tst();
}

void data_tst(void)
{
        uint temp = 0,yy = 0;
        temp = sizeof(uchar);
        yy = sizeof(uint);
}
下面上图:

http://cache.amobbs.com/bbs_upload782111/files_36/ourdev_620107PP2VN4.JPG
我调试时候的图片 (原文件名:keil.JPG)


当单步进入data_tst()函数的时候,汇编是:
C:0x0013    020016   LJMP   data_tst(C:0016)
但是再继续往下执行时 下一条指令是:
C:0x0016    22       RET      
直接就返回了,那我写的函数语句呢???
再往下执行就是 :
C:0x0017    00       NOP      
C:0x0018    00       NOP
C:0x0019    00       NOP
C:0x001A    00       NOP

难道是我的keil版本的问题??


http://cache.amobbs.com/bbs_upload782111/files_36/ourdev_620109FWZHQV.JPG
我的keil版本 (原文件名:keil_version.JPG)


大家有遇到过这个问题吗?

yuanbangyin 发表于 2011-3-5 11:51:48

从来没有见过断点设置在最后的右括号上面的,等到执行ret指令的时候,根本不会理会你的中断,直接返回了。

zhuyi25762 发表于 2011-3-5 11:54:05

从来没有见过断点设置在最后的右括号上面的.哈哈,眼神真好

ohmytime 发表于 2011-3-5 12:32:54

回复【1楼】yuanbangyin 袁邦银
从来没有见过断点设置在最后的右括号上面的,等到执行ret指令的时候,根本不会理会你的中断,直接返回了。
-----------------------------------------------------------------------

不是这样的,我才不会把断点设置在最后的右括号上面的!!!
void data_tst(void)
{
    uint temp = 0,yy = 0;
    temp = sizeof(uchar);//我在这一句设置的断点
    yy = sizeof(uint);
}


我是在函数里面设置断点,结果debug的时候,它就成了你看到的样子!
好好看看生成的汇编文件吧

其实我在主函数的某一句设置断点,然后调试的时候在那一句停下。
然后再单步进入data_tst()函数,结果就会直接退出函数的!!

marshallemon 发表于 2011-3-5 12:56:26

真是牛人,感觉你似乎修改了程序没有编译造成的,重新编译下,再进DEBUG

ohmytime 发表于 2011-3-5 13:15:24

回复【4楼】marshallemon
真是牛人,感觉你似乎修改了程序没有编译造成的,重新编译下,再进debug

-----------------------------------------------------------------------

没有啊,我用keil很久了,一切都正常啊,编译好多遍了都,觉得应该没问题的。

难道是win7下不兼容??不会吧,用脚趾头想想都不应该的。
看下面这张图

http://cache.amobbs.com/bbs_upload782111/files_36/ourdev_620131DDBN8K.JPG
看看标出的部分 (原文件名:捕获.JPG)

Oh My God !我的函数里的程序跑哪里去了???

tcp1985 发表于 2011-3-5 13:52:31

是被编译器优化掉了,这便是volatile的神奇作用了,将子函数的局部变量加入volatile即可了

http://cache.amobbs.com/bbs_upload782111/files_36/ourdev_620133Q5MESC.jpg
(原文件名:未命名.jpg)

tcp1985 发表于 2011-3-5 13:57:19

另:不用随便怀疑编译器,人家做编译器的焉是吃干饭的!

KunShan_a_dai 发表于 2011-3-5 14:10:38

回复【7楼】tcp1985你是不是党员
-----------------------------------------------------------------------
你的头像太让人销魂了;
那是谁啊?

tcp1985 发表于 2011-3-5 14:16:15

回复【8楼】KunShan_a_dai
回复【7楼】tcp1985你是不是党员
-----------------------------------------------------------------------
你的头像太让人销魂了;
那是谁啊?
-----------------------------------------------------------------------
是我们东边的邻居,名字不知道。

real_zyf 发表于 2011-3-5 14:23:11

简单来说,编译器发现你的函数完全没意义,于是进去之后就直接结束了

ohmytime 发表于 2011-3-5 14:24:08

回复【6楼】tcp1985 你是不是党员
是被编译器优化掉了,这便是volatile的神奇作用了,将子函数的局部变量加入volatile即可了


-----------------------------------------------------------------------

奇怪了!我不对它进行初始化的时候 编译器是不会对它进行优化的,

uint temp,yy;//这样就不会优化了

uint temp = 0 ,yy = 0;//但是这样就会优化掉!!!!
我以前只听说过对一个IO口进行多次操作,编译器会进行优化,但是想不到今天这样也会被优化掉!

麻烦请讲一下一般在什么情况下会进行优化呢!

tcp1985 发表于 2011-3-5 14:46:07

对于volatile的作用我很多时候也搞不清楚,我将你的程序copy进去不行我就想到是不是被优化掉了,后来加了volatile果然行了。
故开头的时候就说神奇的volatile。
下面有帖子是说volatile的,你可进去看一下。。。
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=460256&bbs_page_no=1&search_mode=4&search_text=tcp1985&bbs_id=9999

ohmytime 发表于 2011-3-5 14:56:25

回复【12楼】tcp1985 你是不是党员
-----------------------------------------------------------------------

多谢了!我去看看!

lcq007 发表于 2011-3-5 20:01:04

哈哈,你被他优化了

skystalker 发表于 2011-3-16 15:57:13

可以在要设断点的函数前加上
#ifdef DEBUG
#pragma OT(3)
#endif
括号里填优化等级,这里是3,这样DEBUG的时候就很方便啦

下面是KEIL的详细说明

OPTIMIZE Compiler Directive
Abbreviation OT

Arguments A decimal number between 0 and 11 enclosed in parentheses optionally followed by SIZE or SPEED to specify code size or execution speed emphasis.

Default OPTIMIZE (8, SPEED)

µVision Options — C51 — Code Optimization.

Description The OPTIMIZE directive sets the optimization level and emphasis the Cx51 Compiler uses when generating object code.

Level Description
0 Constant Folding: The compiler performs calculations that reduce expressions to numeric constants, where possible. This includes calculations of run-time addresses.

Simple Access Optimizing: The compiler optimizes access of internal data and bit addresses in the 8051 system.

Jump Optimizing: The compiler always extends jumps to the final target. Jumps to jumps are eliminated.
1 Dead Code Elimination: Unused code fragments and artifacts are eliminated.

Jump Negation: Conditional jumps are closely examined to see if they can be streamlined or eliminated by the inversion of the test logic.
2 Data Overlaying: Data and bit segments suitable for static overlay are identified and internally marked. The BL51 Linker/Locator has the capability, through global data flow analysis, of selecting segments which can then be overlaid.
3 Peephole Optimizing: Redundant MOV instructions are removed. This includes unnecessary loading of objects from the memory as well as load operations with constants. Complex operations are replaced by simple operations when memory space or execution time can be saved.
4 Register Variables: Automatic variables and function arguments are located in registers when possible. Reservation of data memory for these variables is omitted.

Extended Access Optimizing: Variables from the IDATA, XDATA, PDATA and CODE areas are directly included in operations. Intermediate registers are frequently unnecessary.

Local Common Subexpression Elimination: The compiler detects multiple uses of the same expression or subexpression. The result of the first expression is saved and reused when possible. Superfluous expression calculations are eliminated from the code.

Case/Switch Optimizing: Code involving switch and case statements is optimized using jump tables or jump strings.

Simple Loop Optimizing: Program loops that fill a memory range with a constant are converted and optimized.
5 Global Common Subexpression Elimination: Identical subexpressions within a function are calculated only once when possible. The intermediate result is stored in a register and reused.
6 Loop Rotation: Program loops are rotated if the resulting program code is faster and more efficient. The loop expression of for and while loops is evaluated once at the top of the loop and then at the bottom of the loop. This optimization generates more code but speeds up execution.
7 Extended Index Access Optimizing: DPTR is used for register variables where appropriate. Pointer and array access are optimized for both execution speed and code size.
8 Common Tail Merging: When there are multiple calls to a single function, some of the setup code can be reused, thereby reducing program size.
9 Common Block Subroutines: Recurring instruction sequences are detected and converted into subroutines. The Cx51 Compiler rearranges code to obtain larger recurring sequences.
10 Rearrange Code (Linker Optimization): When detecting common block subroutines, code is rearranged to obtain larger recurring sequences.
11 Reuse of Common Exit Code (Linker Optimization): Identical exit sequences are reused. This may reduce the size of common block subroutines even further. This optimization level generates the most compact program code possible.

Note

Each higher optimization level contains all of the characteristics of the preceding lower optimization level. For example, OPTIMIZE level 9 includes all optimizations of levels 0 to 8.
You may change the optimizer level on a function-by-function basis as needed. For example:
#pragma OT(3)
void funct_1 (void)
{
...
}

#pragma OT(9)
void func_2 (void)
{
...
}

See Also OBJECTADVANCED

Example C51 SAMPLE.C OPTIMIZE (9)

C51 SAMPLE.C OPTIMIZE (0)

#pragma ot(6, SIZE)

#pragma ot(size)

fwluck 发表于 2011-3-16 16:03:29

keil的这个功能确实不好用。伤的次数太多了。

ohmytime 发表于 2011-3-18 12:46:40

回复【16楼】fwluck
keil的这个功能确实不好用。伤的次数太多了。
-----------------------------------------------------------------------

你是说哪个方面?volatile吗?

chengying 发表于 2012-6-11 11:15:08

学习了,伤不起

wangkangming 发表于 2013-3-12 14:30:49

什么时候用volatile还是云里雾里的。。。。

wb156351 发表于 2013-3-12 15:15:00

volatile确实挺麻烦的

user_first 发表于 2013-3-12 15:23:16

LZ,你的那个data_tst()函数没有作用,除非是最低的优化等级才可能给你翻译。翻译出来的也是无用的代码。如果改成有返回指的函数,将返回值赋给单片机的某个特殊功能寄存器,那么编译器就会给你翻译了。

user_first 发表于 2013-3-12 15:27:53

看了一下哦,你的变量还全部是局部的,还什么事都不做,那编译器就更加不会给你翻译了。
页: [1]
查看完整版本: keil有bug吗?我怎么不能单步调试?进来看看!