当前位置:网站首页>汇编语言范例
汇编语言范例
2022-06-21 22:35:00 【序冢--磊】
1、程序的组成(定义段和起始点)
汇编语言由定义好的段构成,三个常用段如下:
数据段、bss段、文本段
所有汇编语言都必须要有文本,这里是可执行程序声明指令码的地方。数据段和bss段是可选的。数据段声明带有初始值的数据元素。这些数据用作汇编语言程序中的变量。bss段声明使用零值初始的数据段,这些元素常用作汇编语言的缓冲区
1)定义段

bss段总是在文本段之前,数据段可以移动到文本段之后
2)定义 起始点
当汇编语言编译成可执行程序后,程序必须知道起始点
[email protected]:~/ass$ ld main
ld: warning: cannot find entry symbol _start; not setting start address为了解决这个问题,_start 标签表示程序指令应该从这里开始,如果找不到这个标签,连接器就会试图找其他起点,但是对于复杂的程序并不能找到起点。
.globl 命令声明外部程序可以访问的标签。如果编写外部汇编语言或者c语言使用的一组工具,就应该使用global命令声明每个函数的段标签
2、创建简单程序
1)cpuid
cpuid是一条汇编语言指令,不容易从高级语言中执行他。

cpuid使用单一寄存器值作为输入,EAX寄存器(用于操作数和结果数的累加器)用于决定cpuid指令生成什么信息。根据EAX寄存器的值,cpuid指令在EBX、ECX、EDX寄存器中生成关于处理器的不同信息。

EBX 包含最低四个字节
EDX 包含中间四个字节
ECX 包含最高四个字节

范例程序获取寄存器值的信息,并按照易读的信息展示给用户。
2)范例程序
编写汇编程序
# cpuid.s extract the the processor vendor ID
.section .data
output:
.ascii "the processor vendor ID is 'xxxxxxxxxxxx'\n"
.section .text
.global _start
_start:
nop
movl $0,%eax
cpuid
movl $output, %edi
movl %ebx,28(%edi)
movl %edx,32(%edi)
movl %ecx,36(%edi)
movl $4,%eax
movl $1,%ebx
movl $output,%ecx
movl $42,%edx
int $0x80
mov $1,%eax
mov $0,%ebx
int $0x80
生成目标文件
as -o cpuid.o cpuid.s链接生成二进制
ld -o cpuid cpuid.o
执行二进制
[email protected]:~/ass$ ./cpuid
the processor vendor ID is 'GenuineIntel'程序分析:
声明一个ascii码字符串
output:
.ascii "the processor vendor ID is 'xxxxxxxxxxxx'\n"声明指令码段和开始标签
.section .text
.global _start程序第一件事是给eax加载0值,获取厂商id,加载后必须要手机分散在三个输出寄存器的指令响应:
movl $output, %edi
movl %ebx,28(%edi)
movl %edx,32(%edi)
movl %ecx,36(%edi)第一条指令创建一个指针,处理内存中声明output变量使用这个指针,output的标签位置会被加载到EDI寄存器中。接下来按照EDI指针,包含厂商ID字符串片段的三个寄存器的内容会被放到数据内存的正确位置。括号外表示output数据位置
其实就是
"the processor vendor ID is 'xxxxxxxxxxxx'\n"xx开始的位置在28,xx有12个字节,然后他把eax、ebx、ecx的12个字节放到xxx里面,然后输出
放好字节后,就可以输出显示信息了
movl $4,%eax
movl $1,%ebx
movl $output,%ecx
movl $42,%edx
int $0x80这段程序其实就是把output写到标准输出里
这个程序使用一个linux系统调用。linux内核提供很多容易的从汇编应用程序访问的内置函数,为了访问这些内核函数,必须要使用指令码,它生成具有0x80的软件中断。执行具体函数由EAX值来决定。如果没有这个内核函数,就必须 发送到正确显示器io地。
write 函数调用参数
eax包含系统调用的值
ebx写入文件描述符
ecx字符串开头edx包含的长度
3、调试程序
[email protected]:~/ass$ as -gstabs -o cpuid.o cpuid.s
[email protected]:~/ass$ ld -o cpuid cpuid.o
[email protected]:~/ass$ gdb cpuid
我们发现构建程序的时候多了一个-gstabs指令
打断点

到了这里就ok了
4、在汇编中使用c函数
使用printf
# cpuid2.s view the CPUID vendor id string using C library calls
.code32
.section .data
output:
.asciz "the processor vendor id is '%s'\n"
.section .bss
.lcomm buffer,12
.section .text
.globl _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
printf 使用输入多个参数,这些参数取决于要显示的变量,第一个变量是要输出的字符串,带有显示变量的适当代码
output:
.asciz "the processor vendor id is '%s'\n"注意是asciz而不是ascii,因为printf要以空字符结尾的字符串作为输出字符串。
因为不需要定义缓冲区的值,所以使用.lcomm命令为他声明12个字节的缓冲区
.section .bss
.lcomm buffer,12字符串在push后使用call调用printf
pushl $buffer
pushl $output
call printf
addl $8,%esp连接c库函数
[email protected]:~/ass$ ld cpuid2 cpuid2.o
ld: cannot find cpuid2: No such file or directory
[email protected]:~/ass$ ld -o cpuid2 cpuid2.o
ld: cpuid2.o: in function `_start':
(.text+0x1f): undefined reference to `printf'
ld: (.text+0x29): undefined reference to `exit'
[email protected]:~/ass$
会发现c库连接不正确
ld -o cpuid2 -lc cpuid2.o 接入动态c库后连接通过,但是仍然执行不正确
[email protected]:~/ass$ ./cpuid2
bash: ./cpuid2: No such file or directory这是因为解析c函数,但是函数本身并没有包含在可执行 程序中。连接器在运行的时候需要找到必须的库文件,显然这个实例并不是这样。

这里比较老了,ubuntu已经没找到这个库,但是原理知道了不做实验了
5.总结
数据段包含特定内存位置中引用的数据。bss段包含未初始化的数据元素,比如工作缓冲区,例子中的buffer缓冲区
模板定以后注意起始点
为了使用c函数,必须要和宿主机的c库连接,为了更好做到这一点,我们学习了新命令dynamic-linker。
边栏推荐
- C. Helping the nature (CF) difference
- buuctf misc 弱口令
- 微博关闭发布多个兼职诈骗信息违规账号:如何打击数据造假灰产
- buuctf misc 间谍启示录
- IDA静态逆向分析工具使用详解
- [Database Course Design] classroom information management system based on SQL Server (with part of source code)
- [RoarCTF2019]黄金6年
- 【typescript】typscript中感叹号和问号的区别
- 【next】nextjs打包出现组件定义缺少显示名称【Component definition is missing display name】
- 【php】mvcs概念(通俗易懂)
猜你喜欢

【taro】taro微信小程序input在苹果手机上光标聚焦不对的解决办法

目标检测、视觉弱监督学习、大脑多模态成像技术等CV综述来了!图像图形学发展年度报告综述专刊!

以父之名活动攻略(可以薅羊毛啦)

Academician Zhang Jun: the latest paper on unmanned intelligence group and its social integration, Journal of the Chinese Academy of Engineering

Katalon框架测试web(八)等待

Npdp| how to do well in product life cycle management?

【yarn】Name contains illegal characters
![[an Xun cup 2019] blowing bass to sweep QR code](/img/38/7bfa5e9b97658acfe24d3aab795bce.png)
[an Xun cup 2019] blowing bass to sweep QR code

洞見數據價值,啟迪數字未來,《數字化的力量》問世
![[actf freshman competition 2020]swp](/img/80/9fe85ee614857c5800c0d0b1ba9a3d.png)
[actf freshman competition 2020]swp
随机推荐
[pwn basics]pwntools learning
pytorch可视化
Get the value value according to the key in the data
metersphere与jenkins的持续集成
SQL tutorial: five SQL skills that data scientists need to master
美国旅游签证面试须知,我来敲重点啦!
谷歌AI大模型LaMDA有朝一日可取代搜索引擎?谷歌研究员:搜索可被重新想象成用户和语言之间的双向对话
[Yugong series] general responsibility allocation principle in June 2022 (IX) - principle of protected variables
Component value transfer: child components transfer data to parent components
redis主从复制(九)
How to uninstall windows SQL Server cleanly?
The ranking list of programming languages has been published in June, and this language should be "gods"
【php】mvcs概念(通俗易懂)
6月编程语言排行榜已出,这门语言要“封神”
Programming dry goods │ PHP common method encapsulation
如何使用tensorboard add_histogram
Mono 的创建
洞见数据价值,启迪数字未来,《数字化的力量》问世
MNIST image classification and comparison based on K-nearest neighbor
[RoarCTF2019]黄金6年