从《七里香》到GCC as汇编语言

本文从周杰伦的《七里香》歌词引发的栈溢出讨论,深入到GCC as汇编语言的学习。讲解了汇编语言的基本语法,包括预处理、注释、符号、表达式、常量和字符串,并分析了汇编指令、段和重定位、符号和标号。通过实例解析了汇编代码中的段错误原因,揭示了汇编语言在理解程序执行中的重要性。
摘要由CSDN通过智能技术生成

0. 起因

上周末下着大雨,自己在家吃着火锅听着歌,听到周杰伦的《七里香》,里面有句歌词:

雨下整夜,我的爱溢出就像雨水

听到“溢出”这个词我脑子里就想到的栈溢出,我就将歌词篡改成“雨下整天,我的占溢出就像雨水”发了朋友圈,并配了下图1。
图1 朋友圈配图

图中包含的是一个简单C的Hello World程序:

#include <stdio.h>

void main() {
   
    char *str = "hello world.";
    *str = 'A';
}

但编译后执行遇到了段错误。
原本这张图是我网上随便档下来的,当时也没太在意,但却在朋友圈引发了讨论。焦点主要存在于:1)这是不是栈溢出;2)这么简单的代码为什么会引发段错误。

讨论是不是栈溢出感觉没什么意义,因为本来就是随便配图。所以令人好奇的是为什么会出现段错误。通过先验知识,我们知道段错误(segmentation fault)一般是因为程序非法访问了某一段地址。代码中hello world是个字符串,在Java等语言中字符串是不可变对象,因此我也猜测C中的字符串是不是也有类似性质,即字符串是只读的。因此我的观点是操作系统将字符串所在的内存区域标记成只读,现在程序进行写操作,显然它没有权限,因此非法。

在我想着怎么去验证我的想法的时候,有前辈直接通过导出的汇编代码看到了真相。

	.file	"test.c"
	.section	.rodata
.LC0:
	.string	"hello world."
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movq	$.LC0, -8(%rbp)
	movq	-8(%rbp), %rax
	movb	$65, (%rax)
	nop
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
	.section	.note.GNU-stack,"",@progbits

从汇编代码中看到,gcc通过.section这个汇编指令将

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值