MIPS GCC 嵌入式汇编(龙芯适用)

mips linux 编译,Linux环境下mips-gcc编译 背景在之后的学习中,需要在自己的mips架构cpu上编写一系列工具。不想使用mips汇编代码编写这些工具,希望使用c语言编写,并编译为mips机器语言。所以这次编译没有编译c库(不能使用自带的头文件),仅仅编译了gcc编译器。搭建环境系统:Ubuntu 16.04 LTS版本前期准备在主目录~下进行编译。编译好的文件放在(安装在)~/gcc-mips文件夹下1、从镜像源上下载binutilssud... 阅读详情

作者: comcat 发表日期: 2007-04-09 18:06     http://comcat.blog.openrays.org/blog.php?do=showone&tid=329

 

当前版本: 0.1


1. GCC 内嵌汇编的基本格式

asm("assembly code");

如:

asm("syscall"); //触发一个系统调用


如果有多条指令,则需在指令尾部添加'\t'和'\n',如:

asm("li v0, 4011\t\n" "syscall");


括号里的字符串 GCC 前端不作分析,直接传给汇编器 as ,故而相联指令间需插入换行符。

'\t' 加入只为排版对齐一些而已,可以使用 gcc -S tst.c -o tst.s 查看生成的 tst.s

因为 GCC 并不对 asm 后括号中的指令作分析,故而如果指令修改一些的寄存器的值,GCC是
不知道的,这个会引入一些问题。

另外 asm 可以替换为 __asm__ ,效果等价。__asm__ 一般用于头文件中,防止关键字 asm
可能与一些变量、函数名冲突。

内嵌汇编如何与 C 变量交换数据?


2. GCC 内嵌汇编扩展格式

asm (
"assembly code"
: output_operand /* 输出参数列表 */
: input_operand /* 输入参数列表 */
: clobbered_operand /* 被改变的操作对象列表 */
);


以一个例子来说明:

如果我们要读取CP0 25 号硬件计数寄存器的值,并返回之,可以这样:

int get_counter()
{
int rst;

asm( /* mfc0 为取cp0 寄存器值的指令 */
"mfc0 %0, $25\t\n" /* %0 表示列表开始的第一个寄存器 */
: "=r" (rst) /* 告诉gcc 让rst对应一个通用寄存器 */
);

return rst;
}


"=r" 中,'=' 为修饰符,表示该操作对象只写,一般用于修饰输出参数列表中。'r' 表示任意
一个通用寄存器。

由于我们只要取得一个值,故而只用到了输出列表。代码中也没修改一些寄存器的值gcc不知道,
(输出、输入列表中的寄存器gcc是知道的)故而被改变的操作对象列表亦可省去。


如果我们要重设CP0 24 号硬件计数器之控制寄存器的值,则:

unsigned int op = 0x80f;

asm volatile(
"mtc0 %0, $24"
: /* 没有输出,列表为空 */
:"r"(op) /* 输入参数,告诉gcc 让op对应一个通用寄存器 */
);


volatile 关键字表示让GCC优化生成代码时,不要移动、删除我们的汇编码。
另外 __volatile__与其含义相同,引入的目的与__asm__是一样的。


如果我们重设后,立即读取CP0 24号寄存器的值,则:

unsigned int rst;
unsigned int op = 0x80f;

asm volatile(
"mtc0 %1, $24\t\n" /* %1 表示 op 对应的寄存器 */
"mfc0 %0, $25\t\n" /* %0 表示 rst 对应的寄存器 */
: "=r" (rst)
: "r" (op)
);



如果我们要操作的对象位于存储器中,我们可以使用 'm' 来修饰输入输出参数,如:

unsigned short data[] = {
0x0, 0x0, 0x0, 0x0,
0x1, 0x3, 0x5, 0x7,
0x1, 0x3, 0x5, 0x7,
};

void pmullh()
{
asm volatile
(
".set mips3\n\t"
".set noreorder\n\t"

"ldc1 $f0, %1\n\t" /* 取 data+4 处的四个数组元素值到 f0 中 */
"ldc1 $f2, %2\n\t" /* 对应输入列表的 *(data+8) */
/* %2 编译后会替换成类似 16($12) 的形式 */


"pmullh $f2, $f2, $f0\n\t" /* 按16位为单位数据相乘,取结果的低位 */

"sdc1 $f2, %0\n\t" /* 将结果写入data的前四个位置 */

".set reorder\n\t"
".set mips0\n\t"

: "=m"(*data)
: "m"(*(data+4)), "m"(*(data+8))
: "$f0", "$f2", "memory"
);
}


注意到使用'm'修饰的操作数,后面括号里跟的不是指针,而是开始的第一个元素值。
%0,%1, %2 依次对应输出列表的一个,输入列表的两个操作数,编译后会被gcc替换
成类似 0($12),8($12),16($12)的形式,其中$12置数组首地址,即: %0等价于0($12)

由于我们嵌入的代码改变了 $f0, $f2 的值,而他们不在输出、输入列表中,故而要将其陈列
于被改变操作数列表(clobbered operand list)中,以告诉gcc 我们改变了他们的值,以免gcc 误判。

因为代码中我们改变了内存中数据的值,如果此前gcc生成的代码读取了该内存处的值,并保
存于寄存器中的话,由于我们更新了这段数据,所以需要告诉gcc在后面要重新加载数据,这
个需要在被改变操作数列表中(clobbered operand list)写入 "memory"。


3. 修饰符

= 只写,常用于修饰所有输出操作数
+ 只读
& 只用于输出,一般和'='一起用,如:"=&r" (val)


4. 其他对输入、输出对象的操作符

可以参看gcc doc 之 5.36 节(Constraints for `asm' Operands)获取更多信息,下面列出MIPS 平台专用的操作符:

`d'
General-purpose integer register

`f'
Floating-point register (if available)

`h'
`Hi' register

`l'
`Lo' register

`x'
`Hi' or `Lo' register

`y'
General-purpose integer register

`z'
Floating-point status register

`I'
Signed 16-bit constant (for arithmetic instructions)

`J'
Zero

`K'
Zero-extended 16-bit constant (for logic instructions)

`L'
Constant with low 16 bits zero (can be loaded with `lui')

`M'
32-bit constant which requires two instructions to load (a
constant which is not `I', `K', or `L')


`N'
Negative 16-bit constant

`O'
Exact power of two

`P'
Positive 16-bit constant

`G'
Floating point zero

`Q'
Memory reference that can be loaded with more than one
instruction (`m' is preferable for `asm' statements)

`R'
Memory reference that can be loaded with one instruction (`m'
is preferable for `asm' statements)

`S'
Memory reference in external OSF/rose PIC format (`m' is
preferable for `asm' statements)


5. 32位下传递64位数据

A. 读取:

long long counter;
asm(
".set mips3\n\t"
"dmfc0 %M0, $25\n\t"
"dsll %L0, %M0, 32\n\t"
"dsrl %M0, %M0, 32\n\t"
"dsrl %L0, %L0, 32\n\t"
".set mips0\n\t"
: "=r" (counter)
);


B. 写入

long long counter = 0x0000001000000100;

asm(
".set mips3\n\t"

"dsll %L0, %L0, 32\n\t"
"dsrl %L0, %L0, 32\n\t"
"dsll %M0, %M0, 32\n\t"
"or %L0, %L0, %M0\n\t"
"dmtc0 %L0, $25\n\t"
".set mips0\n\t"
: "=r" (counter)
);


MIPS Linux内核编译构建环境的搭建 AI的端侧应用离不开各种算力平台,目前形成了CPU+NPU,CPU+FPGA以及CPU+GPU的几类算力搭配,他们各有优势,也各有弱点。先看它们的共同点,从组合名字可以看出,这些组合场景都需要CPU,这是因为NPU,FPGA和GPU的架构特点决定了它们在流水线pipeline,逻辑处理和控制方面要弱于CPU,所以通常作为专用算力加速器的协处理器。 阅读详情

相关推荐

从指令集演进看龙芯3A4000:MIPS64遗产与LoongArch新纪元的交叉编译桥梁

本文深入分析龙芯3A4000处理器在MIPS64指令集遗产与LoongArch新纪元之间的过渡角色,重点探讨了如何构建高效的交叉编译工具链。文章提供了从工具链配置、编译优化到生态兼容性的完整实践指南,为开发者平滑迁移至自主指令集架构提供了关键技术桥梁。

y4z5a6b7的博客 232

安装 MIPS-GCC 交叉编译工具

NSCSCC(龙芯杯)提供的龙芯编译环境。

莫问天涯,莫问归期 3017

龙芯1B开发板开箱实测:从TeraTerm串口调试到RT-Thread项目创建全流程

本文详细介绍了龙芯1B开发板从开箱验收到RT-Thread项目创建的全流程,包括开发环境搭建、工具链配置、串口调试等关键步骤。特别针对国产MIPS架构的特点,提供了环境变量设置、IDE配置和常见问题排查的实用技巧,帮助开发者快速上手龙芯1B开发板的嵌入式开发。

weixin_30512043的博客 423

一步一步搭建mips-linux-gcc-4.4.0交叉编译工具

http://blog.sina.com.cn/circlewood2010 一步一步搭建mips-linux-gcc-4.4.0交叉编译工具   一、准备工作:  工作环境:宿主机:ubuntu10.04  linux-2.6.32-24-generic i686

leolinux的专栏 1万+

新手避坑指南:在Windows上搞定龙芯1B开发环境(MSYS2+SDE Lite工具链配置)

本文详细介绍了在Windows系统上配置龙芯1B开发环境的完整流程,包括MSYS2和SDE Lite工具链的安装与配置、开发板连接与终端设置、项目创建与编译调试等关键步骤。通过实战经验分享,帮助开发者避免常见问题,快速搭建高效的龙芯1B开发环境。

weixin_30915951的博客 419

手把手教你搭建UEFI开发环境:从Windows到龙芯平台的完整指南

本文提供了一份从Windows到龙芯平台的完整UEFI开发环境搭建指南。文章详细阐述了UEFI开发的核心组件与特殊性,并分步讲解了在Windows上为X86平台、在Linux上为X86平台交叉编译,以及最具挑战性的为龙芯(MIPS)平台搭建交叉开发环境的实战流程,涵盖了工具链选择、环境配置、编译调试等关键编程实践,旨在帮助开发者系统掌握跨平台UEFI开发能力。

a1b2c的博客 248

MIPS GCC 嵌入式汇编(龙芯适用) (2008-07-22 14:06)

MIPS GCC 嵌入式汇编(龙芯适用) (2008-07-22 14:06)当前版本: 0.31. GCC 内嵌汇编的基本格式asm("assembly code");如:       asm("syscall");       //触发一个系统调用如果有多条指令,则需在指令尾

LJL1603的专栏 826

Windows 下的 MIPS GCC 交叉编译器

用于 MinGW/MSYS 下的 MIPS 交叉编译器,默认指令集为 mips32r2。

[嵌入式系统-5]:龙芯1B 开发学习套件 -2- LoongIDE 集成开发环境集成开发环境的安装步骤

LoongIDE(龙芯开发工具集成环境)是一款专门用于龙芯计算机开发的集成开发环境(IDE)。龙芯是中国自主研发的高性能处理器架构,LoongIDE是为支持龙芯开发者进行软件开发而开发的工具。LoongIDE提供了一系列工具和功能,旨在简化和加快龙芯平台上的应用程序开发过程。它提供了代码编辑器、编译器、调试器性能分析工具和软件包管理器等功能,以支持全面的软件开发工作流程。LoongIDE提供了一个集成的文本编辑器,支持多种编程语言,如C/C++、汇编语言等,以便开发者编写和编辑源代码。

文火冰糖(王文兵)的博客 5168

龙芯MIPS汇编自学指南

龙芯MIPS汇编自学指南,英文名:Programmed Introduction to MIPS Assembly language ,我将其编译成chm方便大家学习和参阅。 详情:ref :http://chortle.ccsu.edu/AssemblyTutorial/index.html

动态欧拉角与静态欧拉角:从理论到实践的深度解析

本文深度解析了动态欧拉角与静态欧拉角的核心区别与应用场景。静态欧拉角基于固定世界坐标系,适用于全局导航与三维场景编辑;而动态欧拉角基于物体自身坐标系,更符合飞行模拟、机器人控制等直觉操作,但需警惕其固有的万向节死锁问题。文章通过理论结合实战,帮助开发者在机器人、无人机及图形学项目中正确选用与处理旋转表示。

java5的博客 1073

龙芯的全新自主指令集到底强在何处?

近日,龙芯推出自主指令系统架构:LoongArch,本文将从龙芯官方的材料中解读出一些干货内容,供读者们参考。青出于蓝而胜于蓝,那些年 MIPS 教给龙芯的事龙芯的全新自主知识产要指令集 ...

616

计量经济学tempdisagg的python库:年度时序变月度

计量经济学tempdisagg的python库:年度时序变月度

素质云笔记 1528

从点亮屏幕到串口打印:手把手带你完成龙芯1B开发板第一个程序测试

本文详细介绍了龙芯1B开发板从开发环境搭建到串口输出的完整流程,包括工具链配置、RTOS选择、串口通信设置及第一个程序的编写与调试。通过实战演示,帮助开发者快速上手国产MIPS架构开发板,解决常见问题并优化性能。

weixin_30321709的博客 475

【Bluedroid】BLE连接过程详解

Bluedroid BLE的链接过程包括扫描、连接和通信三个基本步骤。通过这些步骤,中央设备和外围设备之间可以建立起稳定、高效的通信链路,实现数据传输和控制操作。

byte轻骑兵的技术小窝 1876

数学之美:欣赏超越数e

文章目录一、e为何物?二、利息与e的关系1、利息问题2、计算利息3、欣赏螺旋线(1)螺旋线概述(2)绘制螺旋线三、e和π 一、e为何物? e是一个无限不循环小数,其值约等于2.718281828…,它是一个超越数,有时也称为欧拉数(Euler’s Number)。 以e为底的对数称为自然对数(Natural Logarithm),数学中使用自然这个词的还有自然数(Natural Number)。 这里的“自然”并不是现代人所习惯的“大自然”,而是有点儿“天然存在,非人为”的意思。 二、利息与e的关系

howard2005的专栏 1717

龙芯平台Linux 4.19内核编译报错与排错全攻略

在嵌入式与国产化平台开发中,交叉编译是构建内核的基础技能,其核心在于工具链、目标架构与内核源码三者的版本匹配。不同指令集体系(如MIPS与LoongArch)对应着完全不同的编译路径,而环境变量、配置文件、链接脚本中的细微疏漏,都可能导致汇编报错、重定位溢出或启动失败。掌握内核编译的原理,不仅能应对龙芯平台的常见问题,也能为其他国产芯片的BSP开发提供方法论。面向信创、工控、轨交等对自主可控有明确要求的场景,快速定位并解决编译故障是提升交付效率的关键。本文以Linux 4.19在龙芯平台上的实战为例,系统梳

weixin_29178069的博客 307

【Nginx学习】5步揭秘Nginx邮件代理模块:邮件代理服务器的功能与实现

Nginx的邮件代理模块(Mail Proxy Module)允许Nginx作为邮件代理服务器,支持SMTP、POP3和IMAP协议。这使得Nginx可以作为一个高性能的邮件网关,用于过滤垃圾邮件、病毒扫描、负载均衡等任务。简单来说,Nginx在这里就像是一个邮递员,负责将邮件从发件人手中安全、快速地送到收件人手中。通过上述的解析,我们可以看到Nginx在邮件代理模块中的设计和实现。从配置解析、连接处理,到协议处理、SSL/TLS加密和日志记录,每一步都至关重要。

java专栏 1312

龙芯1C300B开发板Linux系统移植启动调试记录

龙芯1C300B开发板Linux系统移植启动调试记录

sinat_41639799的博客 1665

【无人机编队】基于matlab虚拟leader无人机编队仿真【含Matlab源码 3279期】

虚拟leader无人机编队仿真 完整代码,包运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 837

EEMD算法原理及应用

本博客主要概括EEMD算法的背景、原理以及应用,利用EEEMD对信号进行分解,然后选择有用的IMF分量进行叠加以完成信号的重构,从而实现对信号降噪。本文配套的源代码见文中链接,可供大家免费下载。

总结论文中的算法并给出论文的复现代码 4万+

龙芯1B嵌入式开发环境搭建:LoongIDE安装与交叉工具链配置

嵌入式交叉开发,是指在 PC 上借助交叉编译工具链,为目标硬件生成可执行程序的开发方式。对于 MIPS 架构的龙芯1B,处理器采用小端格式,工具链前缀通常为 mipsel,且无硬件浮点单元,需关注软浮点 ABI。其技术价值在于把编辑、编译、下载、调试串成一条可复用链路,降低裸机与 Linux 系统开发的环境门槛。典型场景是龙芯1B 开发学习套件,通过串口终端和 TFTP 下载完成程序部署。LoongIDE 集成开发环境把 Eclipse、交叉工具链、串口与调试配置整合起来,安装重点在于 JDK 版本、英文路

weixin_33947521的博客 296

WinCC实现定时存储数据至SQLServer

环境 Win10 WinCC V7.5 SQL Server 2016 运行结果 流程 WinCC变量 全局VB脚本 (我设置的是每2秒存一次,因此周期性触发器设置1秒)

skr? 3987
上一篇: Linux 存储管理分析札记
下一篇: 龙芯下汇编语言编程(2)
LonlyGod
博客等级 码龄15年 32粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值