hi 大家好:
表达式一:
char a = 'a';
表达式二:
char *a = "a";
这两个c表达式再汇编中的区别是什么?
我有objdump -D 得到的汇编代码中发现了表达式一中的内容为:
movb $0x61 0x1f(%esp)
我的理解是是立即数0x61就是字符 a。不知道这样理解对吗?
当使用第二个表达式的时候编译后再dump在汇编文件中没有找到相应的0x61。
当做字符串处理的时候再汇编代码中式怎么处理这个字符串 变量的?
软件环境:ubuntu 12.04
硬件环境:dell optiplex 380
gcc版本:4.6.3
谢谢大家。
汇编 ubuntu
------解决方案--------------------
第一个理解是对的。
第二个,你说的 ubuntu 环境不知道,在 Windows 环境下,一般是在 .const 节中有个 "a", 0 的字符串,然后该字符串地址赋予 a 变量如 [esp+??] 或 0x??(%esp) 吧。
------解决方案--------------------
字符型变量应该是定义在内存或寄存器中的。如果以立即数的形式出现的话,这就是个字符型常量,而不是变量。我记得在保护模式下除了操作系统,其他程序是没有权限修改自己的代码段的。所以说这个字符的值是无法修改的,因此说它是个常量,而不是变量。另外汇编语言事实上定义这个概念是很模糊的,对应的类型的概念也很模糊,基本上是你对这个变量进行什么操作,这个变量就是什么类型。(当然模糊不模糊还取决于写程序的人,但使用常规方法做到不模糊还是比较不容易的)比如你对大于等于'a'小于等于'z'的某个字节进行加'A'-'a'的操作的话,这个字节就是字符型常量。我用过的汇编语言的编译器根本就不会进行类型检查,所以说完全对应应该是不可能有的。类似的方法应该是如果定义到内存中的话,字符类型就是label db 'a'这种,字符串就是 label db 'asdfasdf',0这种,区别和C语言是差不多的,主要就是字符串有结束标记。注意如果是在dos里面的话,结尾最好是用'$',因为系统中断提供的字符串显示函数是以'$'作为结束标记的。如果是定义到寄存器中的话,就是 mov 8位寄存器,'a',字符串使用常规手段是无法定义到寄存器中的,因为字符串一般会有地址递增的操作,如果使用寄存器是很不方便的。另外使用汇编进行字符串操作还可以有更灵活的方式,比如可以这样定义:
label1 label2-$,'asjflasjdlfajals' ;这个地方可能有错误,很长时间没用汇编了,label2-$是取后面的字符串的长度的意思。
label2
这样进行字符串复制的时候可以直接用字符串传送指令,效率更高。
另外你提到的找不到C的可执行程序中的字符串痕迹,这个可能是因为字符串操作都是以字符串的首地址作为标记的,而这个地址的值是不确定的。