AT&T汇编语言——简单实例及工具演示

今天就来用详细实例代码来运用一下昨天所说的仅仅个工具的使用方法吧

这几个实例基本的目的是来熟悉一下汇编相关工具的使用方法及应用一下昨天刚说的汇编程序模板

我们用到的工具主要有as,ld,gcc,gdb,当然。它们是执行在linux系统下的

废话少说,直接来样例了。嗯,再说一句,以下的样例是參考或来自《汇编语言程序设计》Richard Blum的

例一:打印出"hello,world!"

#hellowrold.s print "hello,world!"

.section .data
	output:
		.ascii "hello,world\n"

.section .text
.globl _start
_start:
	movl $4, %eax
	movl $1, %ebx
	movl $output,%ecx
	movl $12,%edx
	int  $0x80
	movl $1, %eax
	movl $0, %ebx
	int  $0x80

简单说一下代码:

首先,在数据段中声明一个字符串:

output:
		.ascii "hello,world\n"

.asscii声明使用ASCII字符声明一个文本字符串。字符串元素被提前定义而且放在内存中,其起始内存位置由标签output指示。

以下是声明程序的指令码段和一般的起始标签,_start是链接器默认的起始代码:

.section .text
.globl _start
_start:

以下是直接调用write系统调用来显示文本内容

        movl $4, %eax
	movl $1, %ebx
	movl $output,%ecx
	movl $12,%edx
	int  $0x80

Linux下write系统调用的參数:

EAX包括系统调用值。write是4

EBX包括要写入的文件描写叙述符,我们知道,Linux终端中0表示标准输入。1表示标准输出。2表示错误输出,这里将1传入EBX,也就是表示标准输出

ECX包括字符串的开头

EDX包括字符串的长度

用样。以下也是系统调用 ,1表示退出函数,返回值为0

        movl $1, %eax
	movl $0, %ebx
	int  $0x80

编译执行结果例如以下:

先解释编译參数,

第一步:首先编译成二进制文件  as --32 -o hellowrold.o hellowrold.s

as表示用as汇编器。

--32表示将目标代码编译成ia-32代码格式

-o hellowrold.o 表示目标文件是hellowrold.o(好像,写错文件名称了Orz)

hellowrold.s就是源码了(本来要定成helloworld.s的,错了就错了吧)

第二步:然后。将hellowrold.o链接成可运行文件

ld -m elf_i386 -o hellowrold hellowrold.o

ld表示是用ld链接

-m elf_i386 表示生成32 elf位 elf格式文件

-o hellowrold表示生成的文件是hellowrold

hellowrold.o 是在第一阶段生成的二进制文件

再来试试gdb这个调试工具。汇编器as的多了个參数 -g,表示生成debug 代码。gdb  hellowrold执行调试,界面例如以下:

gdb的使用方法主要有几个:list显示代码,break设置段点。 info register显示全部寄存器的值。print打印特定变量的值。x显示特定内存位置的值,step下一指令,run执行代码。

演示一下:

list,列出代码

break设置断点。这里是在特定的标签中设置,break有下面方式设置断点:

1.到达某个标签

2.到达源码中的某个行号

3.数据值到达特定值

4.函数运行了指宝的次数之后

print 打印出对应的值。print 的输出格式有:

print/d 输出十进制值

print/t  输出二进制值

print/x 输出十六进制值

info register 打印出全部寄存器值

当然,我们的样例仅仅要改一下,将 代码入口标签_start改成main就能够用gcc来编译。

gcc -m32 -o hellowrold hellowrold.s  

就能够编译成功了。

例二、以下再说个在汇编语言中调用c函数库的样例。

.section .data
	output:
		.ascii "The number is %d\n"
.section .bss
	.lcomm buffer,18
.section .text

.globl _start
_start:

	pushl $520
	pushl $output
	call  printf
	addl  $8,%esp
	pushl $0
	call  exit

例如以下方法编译该代码,能够看出。ld链接的时候多了几个參数。

让我来一一说一下多出来的两个參数的含义吧。

我们知道 ,在linux中,把C函数连接到汇编语言程序有两种方法。第一种中做静态链接(static linking).静态链接把函数目标代码直接连接到应用 程序的可运行程序文件里。

这样会创建巨大的可运行程序。并且,假设同一时候运行程序的多个实例,会造 成内在浪费(每一个函数都有其自己的同样函数拷贝)

另外一种方法是动态链接。

在Linux中,标准C的动态库位于lib.so.x文件里,在我的系统(ubutnu 14.04 )中,这个文件是libc.so.6。因为我採用兼容方式执行,所以,我的系统有两个该文件,一个是32位的(/lib/i386-linux-gnu/libc.so.6),另一个是64位的(/lib/x86_64-linux-gnu/libc.so.6)。在使用gcc时。gcc是自己主动将c语言链接到该库。我们使用ld。为了链接libc.so文件。必须使用gnu连接器的-l 參数,不用指定完整的库名称。连接器如果在它能找到的位置存在libxso文件。基中x是命令行參数指定的库名称。我们的是c,故使用

-lc

理论上,我们不用加參数 -dynamic-linker就能够执行了。可其实,编译是通过了。可是执行不了。

bash: ./print: No such file or directory

为什么呢?

问题在于连接器是可以解析C函数了,可是函数本身没有包括在终于可执行程序中。链接器如果执行时程序可以找到该库文件。所以编译进不出错。但其实。我们的程序找不到该库文件。为了解决问题,还必须指定在程序执行时载入动态库的程序。对于LINUX,这个程序是linux.so.2,在我的系统下,它位于/lib下。为了指定这个程序,必须使用gnu链接器的 -dynamic-linker,故还要加入參数

-dynamic-linker

事实上,我们也能够直接用 gcc编译,仅仅要把_start标签改成 main就能够例如以下方法 编译了

gcc -o print print.s

时间: 2024-10-10 07:38:56

AT&T汇编语言——简单实例及工具演示的相关文章

AT&T汇编语言——简单实例及工具演示

今天就来用具体实例代码来运用一下昨天所说的只个工具的用法吧 这几个实例主要的目的是来熟悉一下汇编相关工具的用法及应用一下昨天刚说的汇编程序模板. 我们用到的工具主要有as,ld,gcc,gdb,当然,它们是运行在linux系统下的 废话少说,直接来例子了.嗯,再说一句,下面的例子是参考或来自<汇编语言程序设计>Richard Blum的 例一:打印出"hello,world!" #hellowrold.s print "hello,world!" .se

使用Resources类搭建Unity简单的资源管理工具类

Unity资源加载的方式有: 1.脚本拖拽(本地) 2.Resources加载(本地) ★ 3.AssetBundle加载(本地,远程[www])★ 本篇将使用Resources类搭建一个简单的资源管理工具类 Resources是Unity下的特殊文件夹,使用需自行创建Resources文件夹(命名必须正确) 使用Resources文件夹就需要用到Resources类的一些方法,如下: Resources类 Load 从Resources文件夹加载单个资源(可指定类型) LoadAll 从Res

【SSH进阶之路】Hiberante3搭建开发环境+简单实例(二)

Hibernate是非常典型的持久层框架,持久化的思想是非常值得我们学习和研究的.这篇博文,我们主要以实例的形式学习Hibernate,不深究Hibernate的思想和原理,否则,一味追求,苦学思想和原理,到最后可能什么也学不会,从实践入手,熟能生巧,思想和原理自然而然领悟. 上篇博文:[SSH进阶之路]Hibernate基本原理,我们介绍了Hibernate的基本概念.Hibernate的核心以及Hibernate的执行原理,可以很好帮助我们认识Hibernate,再看这篇博客之前,请先回顾上

【转】Android Https服务器端和客户端简单实例

转载地址:http://blog.csdn.net/gf771115/article/details/7827233 AndroidHttps服务器端和客户端简单实例 工具介绍 Eclipse3.7 Tomcat 6.0.18(免安装版) Android2.1开发环境(在Eclipse中配置好) 前提条件 JDK环境要使用我们自己安装的,笔者JDK安装目录为D:\Java\jdk1.6.0_22,在Eclipse的Window-preference-installedJREs中,只选用我们自己安

【zTree】简单实例与异步加载实例

[zTree]简单实例与异步加载实例 我们在项目中经常会需要用到树,这次按照数据库存储的特点重新了做一个小demo,使用zTree来实现这个功能. 简单实例: 首先我们需要在界面中引入代码,很简单,但是很重要,它用来存放加载的树. ps:添加ztree的引用,下载地址:http://www.ztree.me/v3/main.php#_zTreeInfo [html] view plain copy <span style="font-family:KaiTi_GB2312;font-siz

JAVA RMI远程方法调用简单实例[转]

RMI的概念 RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机上的对象可以调用另外 一台计算机上的对象来获取远程数据.RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径.在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开发方式没有使用面向对 象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote

gtk+blade+anjuta 的简单实例

gtk+blade+anjuta 的简单实例我的系统 ubuntu 12.04 1>  选择源 不正确会有很多问题,速度慢,找不到安装的软件.163的源就不错 http://mirrors.163.com/.help/ubuntu.html 如页面提示操作后, apt-get install update ; apt-get install upgrade 2>  安装软件 apt-get install build-essential  #据说包含包含 一些基本工具,linux机器一般都具有

主题:Java WebService 简单实例

链接地址:主题:Java WebService 简单实例    http://www.iteye.com/topic/1135747 前言:朋友们开始以下教程前,请先看第五大点的注意事项,以避免不必要的重复操作. 一.准备工作(以下为本实例使用工具) 1.MyEclipse10.7.1 2.JDK 1.6.0_22 二.创建服务端 1.创建[Web Service Project],命名为[TheService].   2.创建[Class]类,命名为[ServiceHello],位于[com.

简单实例一步一步帮你搞清楚MVC3中的路由以及区域

我们都知道MVC 3 程序的所有请求都是先经过路由解析然后分配到特定的Controller 以及 Action 中的,为什么这些知识讲完了Controller Action Model 后再讲呢?这个东西我个人感觉比较的抽象吧!如如您有基础,看起来一点也不费力,如果您没有基础的话,您连Controller  Action 都不知道是什么,那您怎么理解路由呢?嘿嘿仅仅是个人的看法!如果您还没有了解MVC 3 的一些基本的信息请您按照我下面的导航来,先了解MVC 3 的其他知识,然后再看下这篇文章.