C指针原理(44)-汇编基础
AT&T匯編語語言中的數(shù)據(jù)段與數(shù)據(jù)類型
.data段定義的數(shù)據(jù)元素保留在內(nèi)存中能夠被指令讀取和寫入;
.rodata段定義的數(shù)據(jù)元素只讀;
.data與.rodata段的數(shù)據(jù)類型:
同時可以使用.fill自動創(chuàng)建10000個數(shù)據(jù)元素,默認為每個字段創(chuàng)建一個字長,并使用零填充它。
在.data與.rodata段中定義的數(shù)據(jù)將從內(nèi)存地址由低到高排列。編寫一段簡單的匯編代碼
dp@dp:~ % cat test.s
.section .data
mybuffer:
.fill 100
.section .rodata
mytext:
.ascii “abcde”
val1:
.byte 'a'val2:
.byte 'b'.byte 'c'.section .text
.globl _start
_start:
movl mytext,%eax
movl val1,%ebx
dp@dp:~ %
從對上面程序的反匯編可看出,內(nèi)存地址從低到高放置了mytext(0804807f )、val1(08048084 )、val2(08048085)、mybuffer。
dp@dp:~ % objdump -D test
test: file format elf32-i386-freebsd
Disassembly of section .text:
08048074 <_start>:
8048074:a1 7f 80 04 08 mov 0x804807f,%eax
8048079:8b 1d 84 80 04 08 mov 0x8048084,%ebx
Disassembly of section .rodata:
0804807f :
804807f:61 popa
8048080:62 63 64 bound %esp,0x64(%ebx)
8048083:65 gs
08048084 :
8048084:61 popa
08048085 :
8048085:62 .byte 0x62
8048086:63 .byte 0x63
Disassembly of section .data:
08049088 :
…
.bss段定義的數(shù)據(jù)元素為未初始化的變量,在運行時對其進行初始化。
可分為數(shù)據(jù)通用內(nèi)存區(qū)域和本地通用內(nèi)存區(qū)域
本地通用內(nèi)存區(qū)域不能從本地匯編代碼之外進行訪問。
.text段存放代碼
在代碼段中用“;”表示注釋
匯編代碼如下:
dp@dp:~ % cat test1.s
.section .rodata
output:
.asciz "the number is %d\n".section .data
value:
.int 0,0,0,0,0,0,0,0,0,0.section .text
.globl main
main:
movl $0,%ecx
loopset:
;基地址(存在寄存器中的偏移地址,存在寄存器中的數(shù)據(jù)元素索引,存在寄存器中的數(shù)據(jù)元素大小)
movl %ecx,value(,%ecx,4)inc %ecxcmpl $10,%ecxjne loopsetmovl $0,%ecx
loopprint:
movl value(,%ecx,4),%eaxpushl %ecxpushl %eaxpushl $outputcall printfadd $8,%esppopl %ecxinc %ecxcmpl $10,%ecxjne loopprint編譯并運行
dp@dp:~ % gcc -o test1 test1.s
dp@dp:~ % ./test1
the number is 0
the number is 1
the number is 2
the number is 3
the number is 4
the number is 5
the number is 6
the number is 7
the number is 8
the number is 9
上述代碼 ,先在.data可讀寫區(qū)域放置10個初始值為0的int值,然后在程序中通過loopset標記和jne語句完成一個循環(huán),將它們的值依次賦值為0到9,最后通過loopprint標記和jne語句完成循環(huán),調(diào)用c庫的print語句將這些數(shù)輸出。inc表示自增1,而dec表示自減1 。
棧是由高地址向低地址增長的,當棧增加內(nèi)容,將導(dǎo)致棧頂指針減少,否則,導(dǎo)致棧頂指針增加
在print語句執(zhí)行返回后,清空執(zhí)行print在堆棧中的生成垃圾,add 8,8,%esp,拋棄為調(diào)用printf函數(shù)準備的參數(shù) ,棧頂有ESP寄存器來定位,壓棧的操作使得棧頂?shù)牡刂窚p小,彈出的操作使得棧頂?shù)牡刂吩龃?#xff0c;因此這里相當于直接彈出壓入的2個%eax(指向需要輸出的數(shù)據(jù))和8,output參數(shù),前面有調(diào)用:
pushl %eax
pushl $output
在上面這2個壓棧之前,還調(diào)用了
pushl %ecx
其作用在于,保存%ecx的值,因為c庫的printf函數(shù)會破壞%ecx寄存器的值,一般使用堆棧來保存可能被破壞的值,執(zhí)行完printf完畢后,再還原:popl %ecx
總結(jié)
以上是生活随笔為你收集整理的C指针原理(44)-汇编基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: restify mysql_[菜鸟试水]
- 下一篇: null、undefined、NaN区分