C指针原理(21)-C指针基础-ATT汇编
helloworld-高級(jí)版
.section .data#初始化的變量 output:.ascii "hello,world\n"#要打印的字符串,.data為初始化值的變量。output是標(biāo)簽,指示字符串開(kāi)始的位置,ascii為數(shù)據(jù)類型 .section .bss#未初始化的變量,由0填充的緩沖區(qū).lcomm num,20#lcomm為本地內(nèi)存區(qū)域,即本地匯編外的不能進(jìn)行訪問(wèn)。.comm是通用內(nèi)存區(qū)域。 .section .text#匯編語(yǔ)言指令碼.globl _start#啟動(dòng)入口_start:movl $4,%eax#調(diào)用的系統(tǒng)功能,4為write movl $output,%ecx#要打印的字符串movl $1,%ebx#文件描述符,屏幕為1 movl $12,%edx#字符串長(zhǎng)度int $0x80#顯示字符串hello,worldmovl $0,%eaxmovl $num,%edimovl $65,1(%edi)#A 的asciimovl $66,2(%edi)#B 的ascii movl $67,3(%edi)#C 的ascii movl $68,4(%edi)#D 的asciimovl $10,5(%edi)#\n的ascii movl $4,%eax#調(diào)用的系統(tǒng)功能,4為write movl $num,%ecx#要打印的字符串 movl $1,%ebx#文件描述符,屏幕為1 movl $6,%edx#字符串長(zhǎng)度int $0x80#顯示字符串ABCDmovl $1,%eax#1為退出movl $0,%ebx#返回給shell的退出代碼值int $0x80#內(nèi)核軟中斷,退出系統(tǒng)效果及調(diào)試, -gstabs用于生成調(diào)試信息
xxx-lx@xxx-lx-desktop:~/private/mytest$ as -gstabs -o hello.o hello.s
xxx-lx@xxx-lx-desktop:~/private/mytest$ ld -o hello hello.o
xxx-lx@xxx-lx-desktop:~/private/mytest$ ./hello
hello,world
ABCD
xxx-lx@xxx-lx-desktop:~/private/mytest$ gdb hello
GNU gdb (GDB) 7.1-ubuntu
Copyright ? 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type “show copying”
and “show warranty” for details.
This GDB was configured as “x86_64-linux-gnu”.
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/;…
Reading symbols from /home/xxx-lx/private/mytest/hello…done.
(gdb) list
1 .section .data#初始化的變量
2 output:
3 .ascii “hello,world\n”
4 #要打印的字符串,.data為初始化值的變量。output是標(biāo)簽,指示字符串開(kāi)始的位置,ascii為數(shù)據(jù)類型
5 .section .bss#未初始化的變量,由0填充的緩沖區(qū)
6 .lcomm num,20
7 #lcomm為本地內(nèi)存區(qū)域,即本地匯編外的不能進(jìn)行訪問(wèn)。.comm是通用內(nèi)存區(qū)域。
8 .section .text#匯編語(yǔ)言指令碼
9 .globl _start#啟動(dòng)入口
10 _start:
(gdb) run
Starting program: /home/xxx-lx/private/mytest/hello
hello,world
ABCD
Program exited normally.
(gdb)
linux-匯編-調(diào)用C庫(kù)函數(shù)
1、使用GCC編譯
.section .data
output:
.asciz “http://xxx.iteye.com\n”
.section .text
.global main
main:
push $output
call printf
addl $4,%esp
push $0
call exit
gcc -o test test.s
./test
http://xxx.iteye.com
2、使用匯編器編譯,使用動(dòng)態(tài)鏈接-dynamic-linker,要求后跟SO庫(kù),可使用find / -name ld*.so來(lái)尋找鏈接庫(kù),每個(gè)LINUX版本不一樣,鏈接庫(kù)不一樣,筆者用的是puppy linux,鏈接庫(kù)名為ld-linux.so.2
.section .data
output:
.asciz “http://xxx.iteye.com\n”
.section .text
.global _start
_start:
push $output
call printf
addl $4,%esp
push $0
call exit
as -o test.o test.s
ld -lc -dynamic-linker /lib/ld-linux.so.2 -o test test.o
./test
http://xxx.iteye.com
匯編中通用寄存器的目的
1、EAX和AX:累加器,所有的I/O指令用它來(lái)與外部設(shè)備傳送信息
2、EBX和BX:在計(jì)算存儲(chǔ)單元地址時(shí)常用作基地址寄存器
3、ECX和CX:保存計(jì)數(shù)值
4、EDX和DX:做四字或二字運(yùn)算時(shí),可以把EDX(DX)和EAX(AX)組合在一起存放一個(gè)四字或二字長(zhǎng)的數(shù)據(jù),在對(duì)某些I/O操作時(shí),DX可以放I/O的端口地址
5、ESP和SP:堆棧棧頂指針。
6、EBP和BP:基址寄存器
7、ESI和SI:源變址
8、EDI和DI:目的變址
LINUX/UNIX一般 都安裝了binutils,如果沒(méi)有安裝,在UBUNTU下可以使用apt-get
1.xxx@xxx-laptop:~$ sudo apt-get install binutils
[sudo] password for xxx:
正在讀取軟件包列表… 完成
正在分析軟件包的依賴關(guān)系樹(shù)
正在讀取狀態(tài)信息… 完成
binutils 已經(jīng)是最新的版本了。
下列軟件包是自動(dòng)安裝的并且現(xiàn)在不需要了:
libany-moose-perl libtest-exception-perl libmouse-perl gcc-4.4-multilib
ibus-pinyin-db-open-phrase libclass-c3-perl libdata-optlist-perl
libclass-c3-xs-perl libparams-util-perl lib64gomp1 libmro-compat-perl
lib64gcc1 pinyin-database libsub-install-perl libc6-amd64 libc6-dev-amd64
gcc-multilib libclass-method-modifiers-perl libsub-uplevel-perl lib64stdc++6
libsub-exporter-perl libalgorithm-c3-perl
使用’apt-get autoremove’來(lái)刪除它們
升級(jí)了 0 個(gè)軟件包,新安裝了 0 個(gè)軟件包,要卸載 0 個(gè)軟件包,有 0 個(gè)軟件包未被升級(jí)。
2.也可以在其主頁(yè)上用源代碼安裝
http://www.gnu.org/software/binutils/
1、調(diào)試hello,要求編譯時(shí)指定了-gstabs選項(xiàng)
2、運(yùn)行hello
xxx-lx@xxx-lx-desktop:~/private/mytest$ ./hello
hello,world
ABCD
3、用gdb打開(kāi)hello
xxx-lx@xxx-lx-desktop:~/private/mytest$ gdb hello
GNU gdb (GDB) 7.1-ubuntu
Copyright ? 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type “show copying”
and “show warranty” for details.
This GDB was configured as “x86_64-linux-gnu”.
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/;…
Reading symbols from /home/xxx-lx/private/mytest/hello…done.
4、列出源代碼
(gdb) list
warning: Source file is more recent than executable.
1 .section .data#初始化的變量
2 output:
3 .ascii “hello,world\n”
4 #要打印的字符串,.data為初始化值的變量。output是標(biāo)簽,指示字符串開(kāi)始的位置,ascii為數(shù)據(jù)類型
5 .section .bss#未初始化的變量,由0填充的緩沖區(qū)
6 .lcomm num,20
7 #lcomm為本地內(nèi)存區(qū)域,即本地匯編外的不能進(jìn)行訪問(wèn)。.comm是通用內(nèi)存區(qū)域。
8 .section .text#匯編語(yǔ)言指令碼
9 .globl _start#啟動(dòng)入口
10 _start:
(gdb) list
11 movl $4,%eax#調(diào)用的系統(tǒng)功能,4為write
12 movl $output,%ecx#要打印的字符串
13 movl $1,%ebx#文件描述符,屏幕為1
14 movl $12,%edx#字符串長(zhǎng)度
15 int $0x80#顯示字符串hello,world
16
17 movl $0,%eax
18 movl $num,%edi
19 movl $65,1(%edi)#A 的ascii
20 movl $66,2(%edi)#B 的ascii
5、設(shè)置斷點(diǎn)
(gdb) break 17
Breakpoint 1 at 0x4000c6: file hello.s, line 17.
6、運(yùn)行至斷點(diǎn)
(gdb) run
Starting program: /home/xxx-lx/private/mytest/hello
hello,world
Breakpoint 1, _start () at hello.s:17
7、運(yùn)行下條語(yǔ)句
17 movl $0,%eax
(gdb) next
18 movl $num,%edi
8、顯示所有寄存器的值
(gdb) info registers
rax 0x0 0
rbx 0x1 1
rcx 0x60011c 6291740
rdx 0xc 12
rsi 0x0 0
rdi 0x0 0
rbp 0x0 0x0
rsp 0x7fffffffe2d0 0x7fffffffe2d0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x4000cb 0x4000cb <_start+27>
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
—Type to continue, or q to quit—
gs 0x0 0
(gdb) next
19 movl $65,1(%edi)#A 的ascii
9、按十六進(jìn)制格式輸出edi寄存器的值。/x表示16進(jìn)制,/d表示10進(jìn)制,/t表示二進(jìn)制
(gdb) print/x $rdi
$3 = 0x600128
10、顯示所有寄存器值
(gdb) info registers
rax 0x0 0
rbx 0x1 1
rcx 0x60011c 6291740
rdx 0xc 12
rsi 0x0 0
rdi 0x600128 6291752
rbp 0x0 0x0
rsp 0x7fffffffe2d0 0x7fffffffe2d0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x4000d0 0x4000d0 <_start+32>
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
—Type to continue, or q to quit—
gs 0x0 0
(gdb) next
20 movl $66,2(%edi)#B 的ascii
11、顯示某個(gè)內(nèi)存位置的值,x/nyz,其中n為字段數(shù),y為格式(c為字符,d為10進(jìn)制,x為16進(jìn)制),z為字段長(zhǎng)度(b為字節(jié),n為16位字,w為32位字)
(gdb) next
21 movl $67,3(%edi)#C 的ascii
(gdb) x/3cb &num
0x600128 : 0 '\000’65 ‘A’ 66 ‘B’
(gdb) next
22 movl $68,4(%edi)#D 的ascii
(gdb) next
23 movl $10,5(%edi)#\n的ascii
(gdb) next
25 movl $4,%eax#調(diào)用的系統(tǒng)功能,4為write
(gdb) x/4cb &num
0x600128 : 0 '\000’65 ‘A’ 66 'B’67 ‘C’
12、退出gdb
(gdb)quit
linux-匯編?kù)o態(tài)符號(hào)
.equ 符號(hào)名 值
比如
.equ PI 3.1415
使用方式 為:
movl $PI,%eax
匯編數(shù)據(jù)類型
.ascii 文本字符串
.asciz 以空字符結(jié)尾的文本字符串
.byte 字節(jié)值
.double 雙精度符點(diǎn)數(shù)
.float 單精度符點(diǎn)數(shù)
.int 32位整數(shù)
.long 64位整數(shù)
.octa 16字節(jié)整數(shù)
.quad 8字節(jié)整數(shù)
.short 16位整數(shù)
.single 單精度整數(shù)與float相同
匯編傳送指令
傳送數(shù)據(jù)元素
movl:32位長(zhǎng)度
movw:16位長(zhǎng)度
movb:8位長(zhǎng)度
比如:
movl 源,目標(biāo)
匯編-多值內(nèi)存位置訪問(wèn)(1)
.section .datamyvalue:.byte 67,68,69,70,0mygs:.asciz "%s\n".section .text .globl mainmain:movl $myvalue,%ecxinc %ecx#本來(lái)應(yīng)輸出CDEF,68代表Dpush %ecxpush $mygs call printfpush $0call exitxxx@xxx-laptop:~/private/mytest$ gcc -o test12 test12.sxxx@xxx-laptop:~/private/mytest$ ./test12
DEF
xxx@xxx-laptop:~/private/mytest$
xxx@xxx-laptop:~/private/mytest$ gcc -o test12 test12.s
xxx@xxx-laptop:~/private/mytest$ ./test12
E
xxx@xxx-laptop:~/private/mytest$
.section .datamyvalue:.byte 67,68,69,70,0mygs:.asciz "%c\n".section .text .globl mainmain:#基地址(偏移地址[必須為寄存器],數(shù)據(jù)元素變址,數(shù)據(jù)元素長(zhǎng)度[必須為寄存器],)#基地址+偏移地址+數(shù)據(jù)元素變址數(shù)據(jù)元素長(zhǎng)度movl $2,%ecxmovl myvalue(,%ecx,1),%ebx #將myvalue的變址為2,長(zhǎng)度為1的數(shù)據(jù)值移到ebx中push %ebxpush $mygs call printfpush $0call exit.section .datamyvalue:.byte 67,68,69,70,0mygs:.asciz "%c\n"mygss:.asciz "%s\n" .section .text .globl mainmain:#以下為傳數(shù)值#基地址(偏移地址[必須為寄存器],數(shù)據(jù)元素變址,數(shù)據(jù)元素長(zhǎng)度[必須為寄存器],) #基地址+偏移地址+數(shù)據(jù)元素變址數(shù)據(jù)元素長(zhǎng)度 movl $2,%ecx movl myvalue(,%ecx,1),%ebx #將myvalue的變址為2,長(zhǎng)度為1的數(shù)據(jù)值移到ebx中 push %ebx push $mygs call printf #以下為傳地址 movl $2,%ecx movl $myvalue,%ebx#傳myvalue的地址,變量前加上$ push %ebx push $mygss call printf #以下為傳數(shù)值 movl $2,%ecx movl myvalue,%ebx#傳myvalue第一個(gè)內(nèi)存位置的數(shù)值 push %ebx push $mygs call printf #以下為傳地址,mov %eax,(%ebx)表示把eax值復(fù)制到寄存器ebx所代表內(nèi)存位置中,寄存器中存放著地址movl $71,%edxmovl $myvalue,%eax;movb %dl,2(%eax)#eax指向位置后的第2個(gè)字節(jié),將69改為71movl $myvalue,%ebxpush %ebxpush $mygss call printf push $0call exitxxx@xxx-laptop:~/private/mytest$ gcc -o test12 test12.s
test12.s: Assembler messages:test12.s:0: Warning: end of file not at end of a line; newline insertedxxx@xxx-laptop:~/private/mytest$ ./test12ECDEFCCDGFxxx@xxx-laptop:~/private/mytest$ 匯編的movl使用.section .datamyvalue:.int 67.section .text .globl mainmain:movl $myvalue,%ecxpush $myvaluecall printfpush $0call exitxxx@xxx-laptop:~/private/mytest$ gcc -o test12 test12.sxxx@xxx-laptop:~/private/mytest$ ./test12Cxxx@xxx-laptop:~/private/mytest$總結(jié)
以上是生活随笔為你收集整理的C指针原理(21)-C指针基础-ATT汇编的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java之接口的静态方法的定义和使用
- 下一篇: websocket 学习--简单使用,n