能力值:
( LV5,RANK:70 )
2 楼
C我也遇到很多问题
比如内联汇编中
int i,i2
__asm mov i,i2
编译不过去
还非得这样写
__asm mov eax,i2
mov i,eax
真郁闷
能力值:
( LV2,RANK:10 )
3 楼
字节不对应的问题么?
微软不也在更新编辑器么
能力值:
( LV9,RANK:610 )
4 楼
Intel 汇编语言程序设计 第4章 数据传送,寻址和算术运算
4.1.4 MOV指令 中有一段话
MOV指令对操作数的使用是非常灵活的,只要遵循以下的规则即可
1.两个操作数的尺寸必须一致
2.两个操作数不能同时为内存操作数
3.目的操作数不能是CS,EIP和IP
4.立即数不能直接送段寄存器
你说的问题是第二条提到的
能力值:
( LV2,RANK:10 )
5 楼
mov dword ptr [ebp+??], dword ptr [ebp+??]
你能告诉我这是哪种寻址方式吗?
能力值:
( LV5,RANK:70 )
6 楼
唉,汇编没学合格,闹出笑话了
能力值:
( LV5,RANK:70 )
7 楼
如果有mov dword ptr [ebp+??], dword ptr [ebp+??]这样的寻址方式就好了
能力值:
( LV2,RANK:10 )
8 楼
......你两个操作数都是指针,CPU晕了........
能力值:
( LV5,RANK:70 )
9 楼
那要实现i=i2的值,得非要用寄存器么?
能力值:
( LV2,RANK:10 )
10 楼
不支持内存到内存的寻址。还有short int最大15位~也就是0x7fff
能力值:
( LV2,RANK:10 )
11 楼
bug
能力值:
( LV5,RANK:70 )
12 楼
还有我现在是对mov和lea给搞晕了
能力值:
( LV2,RANK:10 )
13 楼
vs 2008直接出来警告告诉你赋值不对
tt.cpp(5) : warning C4309: '=' : truncation of constant value
'conversion' : truncation of constant value
The type conversion causes a constant to exceed the space allocated for it. You may need to use a larger type for the constant.
The following sample generates C4309: // C4309.cpp
// compile with: /W2
int main()
{
char c = 128; // C4309
}
能力值:
( LV8,RANK:130 )
14 楼
学习了....
能力值:
( LV2,RANK:10 )
15 楼
定义short int a=0x8000, 实际上是1个负数。
如果拿a 和 0x8000做比较,if条件中的0x8000是32位int型的,C语言在不同类型比较的时候会自动做类型转换。所以比较时会将a转换为int型的。显然不相等。
如果定义a为unsigned short int a = 0x8000.结果就是T
能力值:
( LV9,RANK:610 )
16 楼
short int 型的 0x8000是一个负数
二进制是 1000 0000 0000 0000
是10进制的-32768即最小的short int型的负数
能力值:
( LV2,RANK:10 )
17 楼
对应C语法来说:一个是传值,一个是传地址;一个是变量,一个是指针变量。
能力值:
(RANK:350 )
18 楼
编辑了一下你的帖,直接告诉大家冬祭原帖没关系的,和冬祭沟通过了。大家互相讨论才能进步。
标 题: 【原创】一个C里容易忽略的细节
作 者: 冬祭
时 间: 2009-08-11,20:21
链 接: http://bbs.pediy.com/showthread.php?t=95528
能力值:
( LV2,RANK:10 )
19 楼
噢,原来这就是溢出啊!
能力值:
( LV3,RANK:30 )
20 楼
楼上,这个不算溢出,就算是也是假的溢出。
另外楼主对我曾经发的问题进行讨论,很高兴。不过如kanxue老大所引用,原文中的“某论坛”可能是楼主疏忽了,这个论坛正是看雪。有点哭笑不得的感觉。
关于这个问题,我已经找到了理论依据。
K&R的《The C programming language》中提到的整型提升(integral promotion)的概念如下:
"A character, a short integer, or an integer bit-field, all either signed or not, or an object of enumeration type, may be used in an expression wherever an integer maybe used. If an int can represent all the values of the original type, then the value is converted to int; otherwise the value is converted to unsigned int. This process is called integral promotion."
此处正是这个语法点。并不是微软的编译器弄错了。
能力值:
( LV9,RANK:610 )
21 楼
囧~~~不是啦,我看的这个帖子真不是在看雪看到的,是在一个讨论MFC的论坛看的,他们转贴也没说原帖在哪 在看雪看到会说啦。。。 哈哈
感谢冬祭,知道了一个整形提升的概念,还有一个,比较小的立即数(int的范围内)汇编里会当成int型来处理,不管这个立即数多小, 人家微软没错,哈哈~~
能力值:
( LV3,RANK:30 )
22 楼
囧rz。网上很多帖子、教程其实都是出自看雪的。。。
昨天写了一个测试程序:
# include <stdio.h> int main (void)
{
unsigned char a = 0x80 ; if ( a == (char)0x80 )
printf ("T") ;
else
printf ("F") ; getchar () ;
return 0 ;
}
TC和VC得到不同的结果。这个比较有意思……也许是因为TC是16位的,VC是32位的?~
能力值:
( LV9,RANK:610 )
23 楼
你要是把这句 if ( a == (char)0x80 ) 改成这样 if ( a == (unsigned char)0x80 )
结果就应该是一致的啦 (char)0x80 做的有符合扩展, (unsigned char)0x80 是无符号扩展,导致结果就不一样
能力值:
( LV9,RANK:610 )
24 楼
不带unsigned
11: if ( a == (char)0x80 )
0040102C mov eax,dword ptr [ebp-4]
0040102F and eax,0FFh
00401034 cmp eax,80h
00401037 jne main+38h (00401048)
12:
13: printf ("T") ;
00401039 push offset string "T" (00423020)
0040103E call printf (00401410)
00401043 add esp,4
14:
15: else
00401046 jmp main+45h (00401055)
16:
17: printf ("F") ;
00401048 push offset string "F" (0042301c)
0040104D call printf (00401410)
00401052 add esp,4
------------------------------分割线-------------------------------------------------
带 unsigned
11: if ( a == (unsigned char)0x80 )
0040102C mov eax,dword ptr [ebp-4]
0040102F and eax,0FFh
00401034 cmp eax,80h
00401039 jne main+3Ah (0040104a)
12:
13: printf ("T") ;
0040103B push offset string "T" (00423020)
00401040 call printf (00401410)
00401045 add esp,4
14:
15: else
00401048 jmp main+47h (00401057)
16:
17: printf ("F") ;
0040104A push offset string "F" (0042301c)
0040104F call printf (00401410)
00401054 add esp,4
看完这2段反汇编,我彻底晕了 谁来指导指导。。。冬祭大侠?
能力值:
(RANK:300 )
25 楼
unsigned
有符号和无符号的,需要关注的是最高位。是0还是1 是1代表负是0代表正
比如 char 大小由-128到127 你的0x80实际上是-128
而unsigned char 为0到255 如果你比较的时候都是在大于等于0小于等于127 的范围内使用。两者是一致的。
立即数默认为四字节有符号的整数。0x80相当于 0x00000080.