C指针原理(9)-C内嵌汇编
2013-11-06 11:44
302 查看
我们使用m标记可以直接在内存中对数进行操作,前面的例子对变量进行操作时都需要将变量值存储在要修改的寄存器中,然后将它写回内存位置中.
我们直接从xa的内存地址中将xa取出,而不需要再将xa先存储在一个寄存器。
首先,我们看一下AT&T汇编各段的意义
上面列表也许比较抽象,我们从一个C程序生成的中间汇编代码分析:
我们使用gcc -S testcr.c,查看编译生成的汇编代码(为便于理解,将生成的汇编代码进行了注释)
在MAIN函数中char *分配在只读数据段中,实际使用时,只在程序栈中分配一个指针的空间。char[]
在程序栈中分配空间,然后直接使用movl、movw之类的汇编直接把值放入栈中空间。那么在其它函数中声明的呢,可以从以下程序中看出,仍然如此。
生成的中间汇编代码为:
内存的常用分配方式有:
第一,静态分配,所有名字在编译时绑定某个存储位置。不能在运行时改变
第二,栈分配,活动时压入系统栈。
第三,堆分配,以任意次序分配
#include <stdio.h> int main(void){ int xa=2; int xb=6; asm volatile( "subl %1,%0\n\t" :"=r"(xb):"m"(xa),"0"(xb)); printf("%d\n",xb); return 0; }
我们直接从xa的内存地址中将xa取出,而不需要再将xa先存储在一个寄存器。
本博客所有内容是原创,如果转载请注明来源
http://blog.csdn.net/myhaspl/
首先,我们看一下AT&T汇编各段的意义节 | 含义 |
.text | 已编译程序的机器代码 |
.rodata | 只读数据,如pintf和switch语句中的字符串和常量值 |
.data | 已初始化的全局变量 |
.bss | 未初始化的全局变量 |
.symtab | 符号表,存放在程序中被定义和引用的函数和全局变量的信息 |
.rel.text | 当链接器吧这个目标文件和其他文件结合时,.text节中的信息需修改 |
.rel.data | 被模块定义和引用的任何全局变量的信息 |
.debug | 一个调试符号表。 |
.line | 原始C程序的行号和.text节中机器指令之间的映射 |
.strtab | 一个字符串表,其内容包含.systab和.debug节中的符号表 |
#include <stdio.h> void main(){ char *x="xxxx"; char y[]="yy";//y的16进制ASCII码是97,9797的十进制为31097 printf("%s-----%s",x,y); exit(0); }
我们使用gcc -S testcr.c,查看编译生成的汇编代码(为便于理解,将生成的汇编代码进行了注释)
.file "testcr.c" .section .rodata .LC0: .string "xxxx"#使用char *分配 .LC1: .string "%s-----%s" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $32, %esp#分配32字节栈空间,根据变量情况分配 movl $.LC0, 24(%esp)#x变量使用指针(4个字节大小),放入栈中,可以看到,变量分配靠近栈空间的尾部 movw $31097, 29(%esp)#字符'yy'移到main程序的栈中,直接将y变量的值放入栈中 movb $0, 31(%esp)#加上NULL标志,表示字符结束 movl $.LC1, %eax leal 29(%esp), %edx movl %edx, 8(%esp) movl 24(%esp), %edx movl %edx, 4(%esp) movl %eax, (%esp) call printf movl $0, (%esp) call exit .size main, .-main .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" .section .note.GNU-stack,"",@progbits
在MAIN函数中char *分配在只读数据段中,实际使用时,只在程序栈中分配一个指针的空间。char[]
在程序栈中分配空间,然后直接使用movl、movw之类的汇编直接把值放入栈中空间。那么在其它函数中声明的呢,可以从以下程序中看出,仍然如此。
#include <stdio.h> void myprinf(){ char *x="xxxx"; char y[]="yy";//y的16进制ASCII码是97,9797的十进制为31097 printf("%s-----%s",x,y); } void main(){ int num=1; myprint(); exit(0); }
生成的中间汇编代码为:
.file "testcr.c" .section .rodata .LC0: .string "xxxx" .LC1: .string "%s-----%s" .text .globl myprinf .type myprinf, @function myprinf: pushl %ebp movl %esp, %ebp subl $40, %esp movl $.LC0, -16(%ebp) movw $31097, -11(%ebp) movb $0, -9(%ebp) movl $.LC1, %eax leal -11(%ebp), %edx movl %edx, 8(%esp) movl -16(%ebp), %edx movl %edx, 4(%esp) movl %eax, (%esp) call printf leave ret .size myprinf, .-myprinf .globl main .type main, @function main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $32, %esp movl $1, 28(%esp) call myprint movl $0, (%esp) call exit .size main, .-main .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" .section .note.GNU-stack,"",@progbits
内存的常用分配方式有:
第一,静态分配,所有名字在编译时绑定某个存储位置。不能在运行时改变
第二,栈分配,活动时压入系统栈。
第三,堆分配,以任意次序分配
相关文章推荐
- C指针原理(8)-C内嵌汇编
- C指针原理(85)-helloworld的C程序汇编剖析(1)
- C指针原理(86)-helloworld的C程序汇编剖析(2)
- 易语言之内嵌汇编取变量指针的例子
- C指针原理(27)-汇编分析C指针机制
- 内嵌汇编简介
- 比库函数memcpy还高效的memcopy - 美妙的内嵌汇编
- 通过两个汇编实例对高级语言数组实现原理的发现
- C++中的虚函数调用原理的反汇编实例分析(2)
- 复习-C语言内嵌汇编-初级(1)
- 内嵌汇编和内联汇编的使用
- __asm__ __volatile__ GCC的内嵌汇编语法 AT&T汇编语言语法
- C指针原理(55)-C语言-pvm并行计算
- C指针原理(62)-Ncurses-文本终端的图形
- linux 内嵌汇编语法
- C指针原理(79)-递归(3)
- C程序代码中内嵌as汇编(二、占位符)
- GCC的内嵌汇编语法 AT&T汇编语言语法(一)
- ARM GCC 内嵌汇编手册
- GCC中内嵌arm汇编