GCC内嵌汇编学习笔记

1.前言

本文主要对GCC内嵌汇编一文的简要总结,试着用自己的话把GCC汇编的关键点描述出来,以验证自己是否真正理解。本文将以《Linux内核完全注释 v3》中的一个例子进行描述,这个例子我看的时候是非常的懵逼,直到看了GCC内嵌汇编一文。

2. 实例说明

在这里插入图片描述

GCC内嵌汇编的基本结构

__asm ("汇编语句列表"
	:输出寄存器
	:输入寄存器
	:会被修改的寄存器);
  1. 汇编语句列表
    就是普通的一组汇编语句;

  2. 输出寄存器
    表示寄存器的数据赋值给一个表达式作为输出。

注:
(1) 出现在输入寄存器或输出寄存器括号中的内容称为表达式, 如上例中__res,seg和*(addr)
(2) 在输入寄存器或输出寄存器中如果有多个表达式将用逗号隔开
(3)从输出寄存器到输入寄存器所出现的表达式将依次编号,如上例中__res被编号为0, seg被编号为1, *(addr)被编号为2,依次类推。

上例中输出寄存器为:
“=a” (__res) ,此处a代表将eax寄存器加载到表达式,也就是__res中,=表示输出

  1. 输入寄存器
    表示表达式的值赋值给寄存器作为输入。
    上例中:
    “0” (seg), “m” (*(addr)), 此处的0表示与表达式0使用同样的寄存器,而表达式0为__res它使用eax寄存器,所以seg也将使用eax寄存器,即seg会赋值给eax

  2. 会被修改的寄存器
    是告诉编译器这里面出现的寄存器会被修改,请不要占用。

所以如上语句进行翻译如下:

register char __res; //定义寄存器变量__res
push %fs            //将fs寄存器入栈
mov %ax, %fs        //将eax的内容赋值给fs, 而通过输入寄存器可知eax内容为seg,因此也就是将seg
                    //的内容赋值给%fs
movb %fs:%2, %al    // %2为表达式2即*(addr), 因此是将seg:*(addr)的1字节内容放到al寄存器
pop %fs             //恢复fs的值

综上就是将从seg段偏移addr的地方取一个字节

参考文档

  1. https://blog.youkuaiyun.com/littlehedgehog/article/details/2259665
    GCC内嵌汇编
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值