日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C指针原理(9)-C内嵌汇编

發(fā)布時間:2025/3/12 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C指针原理(9)-C内嵌汇编 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們使用m標記可以直接在內存中對數(shù)進行操作,前面的例子對變量進行操作時都需要將變量值存儲在要修改的寄存器中,然后將它寫回內存位置中.

#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先存儲在一個寄存器。

首先,我們看一下AT&T匯編各段的意義

節(jié) 含義
.text 已編譯程序的機器代碼
.rodata 只讀數(shù)據(jù),如pintf和switch語句中的字符串和常量值
.data 已初始化的全局變量
.bss 未初始化的全局變量
.symtab 符號表,存放在程序中被定義和引用的函數(shù)和全局變量的信息
.rel.text 當鏈接器吧這個目標文件和其他文件結合時,.text節(jié)中的信息需修改
.rel.data 被模塊定義和引用的任何全局變量的信息
.debug 一個調試符號表。
.line 原始C程序的行號和.text節(jié)中機器指令之間的映射
.strtab 一個字符串表,其內容包含.systab和.debug節(jié)中的符號表

上面列表也許比較抽象,我們從一個C程序生成的中間匯編代碼分析:

#include <stdio.h>void main(){char *x="xxxx";char y[]="yy";//y的16進制ASCII碼是97,9797的十進制為31097printf("%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, @functionmain:pushl %ebpmovl %esp, %ebpandl $-16, %espsubl $32, %esp#分配32字節(jié)??臻g,根據(jù)變量情況分配movl $.LC0, 24(%esp)#x變量使用指針(4個字節(jié)大小),放入棧中,可以看到,變量分配靠近??臻g的尾部movw $31097, 29(%esp)#字符'yy'移到main程序的棧中,直接將y變量的值放入棧中movb $0, 31(%esp)#加上NULL標志,表示字符結束 movl $.LC1, %eaxleal 29(%esp), %edxmovl %edx, 8(%esp)movl 24(%esp), %edxmovl %edx, 4(%esp)movl %eax, (%esp)call printfmovl $0, (%esp)call exit.size main, .-main.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3".section .note.GNU-stack,"",@progbits

在MAIN函數(shù)中char *分配在只讀數(shù)據(jù)段中,實際使用時,只在程序棧中分配一個指針的空間。char[] 在程序棧中分配空間,然后直接使用movl、movw之類的匯編直接把值放入棧中空間。那么在其它函數(shù)中聲明的呢,可以從以下程序中看出,仍然如此。

#include <stdio.h>void myprinf(){char *x="xxxx";char y[]="yy";//y的16進制ASCII碼是97,9797的十進制為31097printf("%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, @functionmyprinf:pushl %ebpmovl %esp, %ebpsubl $40, %espmovl $.LC0, -16(%ebp)movw $31097, -11(%ebp)movb $0, -9(%ebp)movl $.LC1, %eaxleal -11(%ebp), %edxmovl %edx, 8(%esp)movl -16(%ebp), %edxmovl %edx, 4(%esp)movl %eax, (%esp)call printfleaveret.size myprinf, .-myprinf.globl main.type main, @functionmain:pushl %ebpmovl %esp, %ebpandl $-16, %espsubl $32, %espmovl $1, 28(%esp)call myprintmovl $0, (%esp)call exit.size main, .-main.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3".section .note.GNU-stack,"",@progbits

內存的常用分配方式有:

第一,靜態(tài)分配,所有名字在編譯時綁定某個存儲位置。不能在運行時改變
第二,棧分配,活動時壓入系統(tǒng)棧。
第三,堆分配,以任意次序分配

總結

以上是生活随笔為你收集整理的C指针原理(9)-C内嵌汇编的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。