gas学习
来源:互联网 发布:狼雨seo团队 编辑:程序博客网 时间:2024/04/29 22:07
gas学习
by Jian Lee
- 1. 入门
- 1.1 基本gas程序模板
- 1.2 gas汇编程序伪指令
- 1.3 gas的标签
- 1.4 gas的开始标签
- 1.5 gas中的系统调用
- 1.6 基本 AT&T 汇编风格
- 2. 使用标准C库函数
- 3. 定义数据元素
- 3.1 定义数据元素的命令
- 3.2 赋值命令
- 3.3 bss段
- 3.4 .fill 命令
- 4. MOV命令
1. 入门
利用 cpuid 取得 intel 集容cpu的厂商信息。
.section .dataoutput1: .ascii "当前CPU厂商ID是:"output2: .ascii "xxxxxxxxxxxx\n".section .text.global _start_start: movl $0,%eax cpuid movl $output2,%edi movl %ebx,(%edi) movl %edx,4(%edi) movl %ecx,8(%edi) movl $4,%eax movl $1,%ebx movl $output1,%ecx movl $(output2-output1+14),%edx int $0x80 movl $1,%eax movl $0,%ebx int $0x80编译和链接上面的源代码并运行:
as -o cpuid.o cpuid.s # 汇编源代码为目标文件ld -o cpuid cpuid.o # 链接目标文件为linux可执行的文件./cpuid # 执行
1.1 基本gas程序模板
gas程序分为几个部分,通常有data段和text段。data段存放数据,其 内容会被放在最终的可执行程序中。text段是汇编指令。通常还有 bss段,这里相当于缓存,临时创建。
.section .data ....section .text ...
1.2 gas汇编程序伪指令
一般汇编程序本身会提供一些方便的"指令",但是这些"指令"不是 cpu指令,它们只是方便汇编程序开发者,解释权归汇编程序本身。
gas中的“伪指令”都是以 "." 开头,如上面示例中的一些伪指令:
.section 定义一个段.data 同.section一起定义数据段.ascii 定义一个字符串.text 同.section一起定义程序段.global 定义全局标签
1.3 gas的标签
在gas中的标签等价于一个内存地址,相当于C语言中的指针。不过C语 言的指针还有数据类型属性,这里的数据类型需要自己指定了。
gas中的标签是以冒号结尾的字符串。如示例中的:
output1:output2:
既然gas中的标签是内存地址,这是一个数值。那么,我们可以在gas 程序中对标签进行算术运算,且对于“立即数”能出现的地方,标签也 都可以出现:
movl $(output2-output1+14),%edx
1.4 gas的开始标签
如果用 ld 手动链接程序,则需要在汇编程序中设置一个为 _start: 的开始标签,相当于C程序中的main函数。如果用gcc编译汇编程序, 那么要将 "_start:" 换成 "main:"
如果没有指定 "_start" 标签,可以在运新 ld 命令的时候指定开始标签:
ld -e
1.5 gas中的系统调用
Linux下的汇编程序可以使用系统调用,这样可以避免很多复杂的工作。 在gas里使用系统调用就是在相关寄存器存入系统调用号、调用函数的 参数,再执行 "int $0x80" 命令就可以了。
上例使用了两个系统调用函数: write 和 exit
1.6 基本 AT&T 汇编风格
- 立即数 表示立即数要用"$"符号
- 寄存器 表示寄存器要用"%"符号
- 内存寻址 内存地址要放在寄存器里,才能被寻址,这是intel的cpu指令集规定的。
movl %ebx,(%edi) # 将ebx里面的内容放到edi指向的内存地址单元处。movl %edx,4(%edi) # 将edx里面的内容放到比edi指向的内存地址高4个值的内存单元处。
2. 使用标准C库函数
使用标准C库函数的 cpuid2.s 程序:
.section .dataoutput: .asciz "当前CPU厂商信息是:%s \n".section .bss .lcomm buffer,12.section .text.global _start_start: movl $0,%eax cpuid movl $buffer,%edi movl %ebx,(%edi) movl %edx,4(%edi) movl %ecx,8(%edi) pushl $buffer pushl $output call printf addl $8,%esp pushl $0 call exit汇编、链接并运行:
as -o cpuid2.o cpuid2.sld -dynamic-linker /lib/ld-linux.so.2 -o cpuid2 -lc cpuid2.o
参数说明:
-lc 链接C库/lib/libc.so;如果是-lx,默认链接/lib/libx.so。-dynamic-linker /lib/ld-linux.so.2 使用/lib/ld-linux.so.2加载共享库。
3. 定义数据元素
3.1 定义数据元素的命令
.ascii 文本字符串.asciz 带零结束符的文本字符串.byte 字节值.double 双精度值.float 单精度值.int 32位整数.long 同.int.octa 16字节长度整数.quad 8字节长整数.short 16位整数.single 同.float
有几种数据段:
.section .data 定义通常的数据段,数据被包含在最终程序中.section .rodata 同.data,但是这里定义的数据的值不可修改.section .bss 相当于缓冲
数据定义可以一个标签一个命令一个数据的定义:
output: .asciz "这是一个.asciz定义的字符串"value: .int 100
也可以,一个标签一个命令定义一堆数据:
values: .int 15,20,25,30,35,40,45,50,55,60
无论是哪种形式定义的,数据在内存中都是一个挨着一个的存放的。 这样我们可以用索引来引用它们。
3.2 赋值命令
gas中也可以用一个符号代表一个值,但是符号只不可修改:
.equ factor,3.equ LINUX_SYS_CALL,0x80
3.3 bss段
这个段无须声明特定的类型,只要声明大小:
.comm 声明未初始化数据的通用内存区域.lcomm 声明未初始化数据的"本地"通用内存区域
例如,声明一个1000字节的缓冲区,通过buffer引用这个区域的基址:
.section .bss .lcomm buffer,1000
3.4 .fill 命令
这个命令让汇编器自动创建一段内存区域,并用0填充:
.section .databuffer: .fill 1000
4. MOV命令
gas中把mov命令加了不同后缀,每个后缀表示操作不同的数据大小:
movl 32位movw 16movb 8
下面一个例子把一个值移到ecx寄存器,然后调用linux系统的exit正 常退出。用gdb可以看见寄存器的变化。
# 程序 movetest1.s.section .datavalue: .int 1.section .text.global _start_start: nop movl value,%ecx movl $1,%eax movl $0,%ebx int $0x80
用-gtabs参数汇编程序并链接:
as -gtabs -o movetest1.o movetest1.sld -o movetest1 movetest1.o
使用gdb调试程序:
root@jianlee:~/lab/asm# gdb -q movetest1(gdb) break *_start+1Breakpoint 1 at 0x8048075: file movetest1.s, line 8.(gdb) runStarting program: /root/lab/asm/movetest1Breakpoint 1, _start () at movetest1.s:88 movl value,%ecxCurrent language: auto; currently asm(gdb) print/x %ecxA syntax error in expression, near `%ecx'.(gdb) print/x $ecx$1 = 0x0(gdb) next_start () at movetest1.s:99 movl $1,%eax(gdb) print/x $ecx$2 = 0x1(gdb) s_start () at movetest1.s:1010 movl $0,%ebx(gdb) contContinuing.Program exited normally.(gdb)
把寄存器的值传到内存里:
# movetest2.s 把寄存器的值传到内存中.section .datavalue: .int 1.section .text.global _start_start: nop movl $100,%eax movl %eax,value movl $1,%eax movl $0,%ebx int $0x80
调试程序,查看程序执行过程:
root@jianlee:~/lab/asm# as -gtabs -o movetest2.o movetest2.smovetest2.s: Assembler messages:movetest2.s:0: Warning: end of file not at end of a line; newline insertedroot@jianlee:~/lab/asm# ld -o movetest2 movetest2.oroot@jianlee:~/lab/asm# gdb -q movetest2(gdb) break *_start+1Breakpoint 1 at 0x8048075: file movetest2.s, line 9.(gdb) runStarting program: /root/lab/asm/movetest2Breakpoint 1, _start () at movetest2.s:99 movl $100,%eaxCurrent language: auto; currently asm(gdb) print/x $eax$1 = 0x0(gdb) x/d &value0x804908c <value>:1(gdb) s_start () at movetest2.s:1010 movl %eax,value(gdb) print/x $eax$2 = 0x64(gdb) x/d &value0x804908c <value>:1(gdb) s_start () at movetest2.s:1212 movl $1,%eax(gdb) x/d &value0x804908c <value>:100(gdb) contContinuing.Program exited normally.(gdb)original link:http://jianlee.ylinux.org/Computer/%E6%B1%89%E5%AD%97%E7%B3%BB%E7%BB%9F/gas%E5%AD%A6%E4%B9%A0.html
Linux系统调用
by Jian Lee
- write
- exit
write
eax调用号4ebx将要写入的文件的文件描述符ecx需要写的字符串的内存起始地址edx需要写的字符串的长度movl $4,%eaxmovl $1,%ebxmovl $output,%ecxmovl $14,%edxint $0x80这个例子是将内存地址为output长度为14字节的字符串写到标准输出 (linux下标准输出的文件描述符是1)。
exit
eax1ebx退出状态数字movl $1,%eaxmovl $0,%ebxint 0x80这个例子是返回退出状态号0。通常这代表程序正常结束。
MBR -- 主引导记录
by Jian Lee
- MBR原理
- 结构
- 分区表结构
- Linux下备份修复mbr
- 备份
- 修复
- 修复分区表
MBR原理
结构
偏移值 内容0000 MBR程序代码01BE 分区表(4个分区,每个16字节)01FE 结束标志(aa55)分区表结构
每个分区表都有16字节的大小。它的结构如下:
单位:字节1 如果是引导分区,值为80H;如果不是,值为00H2-4 该分区的起始扇区号5 标志字节 05 扩展分区 82 Linux交换分区 83 ext3分区 0c fat32分区6-8 该分区的终止扇区号9-12 该分区已经使用的扇区数13-16 该分区总共占用的扇区数Linux下备份修复mbr
备份
dd if=/dev/sda of=mbr.img bs=512 count=1修复
dd if=mbr.img of=/dev/sda bs=512 count=1修复分区表
dd if=mbr.img of=/dev/sda bs=512 skip=446 count=66
- gas学习
- [poi2009]gas
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- Gas Station
- ORACLE 10g官网下载地址
- 编程之美学习笔记(一): 1的数目
- 二分查找及其变形
- LinkButton向后台传递参数
- poj 1062
- gas学习
- C#WinForm - 最小化或关闭时隐藏到系统托盘
- Hadoop-个人使用错误记录
- Compressive Tracking——CT跟踪
- SysLink Overview
- 使用构造器装配属性
- gsl安装的安装及配置过程
- 在Eclipse中调试tomcat源代码
- 图像处理之半调色融合