C8051 Register Banks R0-R7

2023-11-08 23:40
文章标签 register r7 r0 c8051 banks

本文主要是介绍C8051 Register Banks R0-R7,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Register Banks

http://www.keil.com/support/man/docs/c51/c51_le_regbankspec.htm

主要讲的register banks 切换,实际使用过程中不建议使用using x。

KEIL编译器在编译函数的局部变量时,可能不是直接调用R0-7,很有可能直接寻址,如下图; 如果中断ISR 使用了using 1描述符,并调用了该函数,进入中断后register banks为1,如果直接从0x05地址取数据会导致错误,正确的应该从R5(实际地址为0x08《Bank 1起始地址》+0x05)取数据。

其实利用好register banks 切换可以加快执行中断的速率(因为不需要将R0-R7压栈),但编译器如果处理不好,或是代码没有考虑到切换,最好不要使用。

如果想用Register Banks 切换,可以考虑在ISR中所调用的函数添加下面的宏:

1.Method 1

#pragma NOAREGS     // 告知编译器下段代码对R0-R7不使用绝对地址

 void function(uint8_t data)

{

}

#pragma AREGS

2.Method 2

#pragma SAVE // Rember current registerbank

#pragma REGISTERBANK(1) // Tel C51 base address of current registerbank.

 void function(uint8_t data)

{

}

#pragma RESTORE // Restore register bank

 

Home » Language Extensions » Function Declarations » Register Banks

In all members of the 8051 family, the first 32 bytes of DATA memory (0x00-0x1F) is grouped into 4 banks of 8 registers each. Programs access these registers as R0-R7. The register bank is selected by two bits of the program status word, PSW.

Register banks are useful when processing interrupts or when using a real-time operating system because the MCU can switch to a different register bank for a task or interrupt rather than saving all 8 registers on the stack. The MCU can then restore switch back to the original register bank before returning.

The using function attribute specifies the register bank a function uses. For example:

void rb_function (void) using 3{...}

The argument for the using attribute is an integer constant from 0-3. Expressions with operators are not allowed. The using attribute is not allowed in function prototypes. The using attribute affects the object code of the function as follows:

  • The currently selected register bank is saved on the stack at function entry.
  • The specified register bank is set.
  • The former register bank is restored before the function is exited.

The following example shows how to specify the using function attribute and what the generated assembly code for the function entry and exit looks like.

stmt level  source12         extern bit alarm;3         int alarm_count;4         extern void alfunc (bit b0);56         void falarm (void) using 3  {7   1           alarm_count++;8   1           alfunc (alarm = 1);9   1         }ASSEMBLY LISTING OF GENERATED OBJECT CODE; FUNCTION falarm (BEGIN)
0000 C0D0       PUSH  PSW
0002 75D018     MOV   PSW,#018H; SOURCE LINE # 6; SOURCE LINE # 7
0005 0500   R   INC   alarm_count+01H
0007 E500   R   MOV   A,alarm_count+01H
0009 7002       JNZ   ?C0002
000B 0500   R   INC   alarm_count
000D  ?C0002:; SOURCE LINE # 8
000D D3         SETB  C
000E 9200   E   MOV   alarm,C
0010 9200   E   MOV   ?alfunc?BIT,C
0012 120000 E   LCALL alfunc; SOURCE LINE # 9
0015 D0D0       POP   PSW
0017 22         RET; FUNCTION falarm (END)

In the previous example, the code starting at offset 0000h saves the initial PSW on the stack and sets the new register bank. The code starting at offset 0015h restores the original register bank by popping the original PSWfrom the stack.

 Note

  • The using attribute may not be used in functions that return a value in registers. You must exercise extreme care to ensure that register bank switches are performed only in carefully controlled areas. Failure to do so may yield incorrect function results. Even when you use the same register bank, functions declared with the using attribute cannot return a bit value.

The using attribute is most useful in interrupt functions. Usually a different register bank is specified for each interrupt priority level. Therefore, you could assign one register bank for all non-interrupt code, a second register bank for the high-level interrupt, and a third register bank for the low-level interrupt.

 Related Knowledgebase Articles

  • C51: XC800: 'Use multiple DPTR registers' may cause runtime errors
  • C51: ABSOLUTE REGISTERS AND USING DIRECTIVE
  • C51: ACCESSING REGISTER BANKS IN C

这篇关于C8051 Register Banks R0-R7的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/373110

相关文章

【C++】win7 64下VC++6.0(Unable to register this add-in because its DLLRegisterServer return an error)

 FileTool.exe用于替换 Visual C++ 使用开发人员 Studio 对象模型中的打开和添加到项目菜单项。也是一个修复 VC6.0打开文件时出错退出的插件。 1. 下载FileTool.exe,并解压 2. 打开VC6.0,点击File-Open Workspace,选择刚解压出来的FileTool.dsw,并确定 3. 点击Bulid-Build FileTool.

chrome 中class not register解决

刚刚上一篇博客更换帐户名为英文后,chrome的taskbar和开始菜单中的快捷方式一直这个问题。 查了查,说什么要改注册表。 但是chrome.exe可以正常工作,数据也都在。 刚刚发现一个特简单的方法。 在C盘搜索chrome, 删除quicklaunch和startmenu的快捷方式,然后把chrome.exe重新固定到这两个地方就ok了。 不过我之前清理注册表了,不知道这个需不

【精讲】PCIe基础篇——BAR(Base Address Register)详解

一、为什么需要BAR         系统中的每个设备中,对地址空间的大小和访问方式可能有不同的需求,例如,一个设备可能有256字节的内部寄存器/存储,应该可以通过IO地址空间访问,而另一个设备可能有16KB的内部寄存器/存储,应该可以通过基于MMIO的设备访问。哪些地址应该使用哪种方式(IO或Memory)来访问它们的内部位置,这是系统软件(即BIOS和OS内核)的工作。因此设备必须为系统软件

MDK报错 .error: unknown register name ‘msp‘ in asm

似乎只能安装 V5的编译器 才能解决,下面是安装链接 https://blog.csdn.net/u011436603/article/details/136419969 V5的编译器 CSDN免费下载链接: =========================================================== 以下办法解决不了 解决办法: 在MDK 桌面图标,右击打开安

RISC-V vector(1) --- vector的引入与register说明

Vector相较于SIMD的优势      这两种实现方案,都是为了实现数据级并行性(存在大量的数据可供程序同时计算); SIMD(Single Instruction Multiple Data)      SIMD是将数据宽度和操作类型,都放在了指令中;          SIMD技术最初通过将64位寄存器的数据拆分成多个8位、16位、32位的形式来实现byte、half word、

【C/C++】存储类型auto、static、register、extern的作用

在C语言中,存储类型指的是数据在内存中的生命周期和可见性。C语言中主要有四种存储类型:自动(auto),静态(static),寄存器(register)和外部(extern)。 目录 autostaticregisterextern auto 在C语言中,auto是一个关键字,用于声明自动变量。 那么什么是自动变量呢?简单来说,自动变量是在函数内部定义的变量,它的生命周期与所在

php--register_globals

可能 PHP 中最具争议的变化就是从 PHP » 4.2.0 版开始配置文件中 register_globals 的默认值从 on 改为 off 了。对此选项的依赖是如此普遍以至于很多人根本不知道它的存在而以为 PHP 本来就是这么工作的。本节会解释用这个指令如何写出不安全的代码,但要知道这个指令本身没有不安全的地方,误用才会。 当 register_globals 打开以后,各种变量都被注

PHP中spl_autoload_register()和__autoload()区别分析

关于spl_autoload_register()和__autoload(),相信大多数都会选择前者了? 看两者的用法:代码如下: //__autoload用法 function __autoload($classname) {     $filename = "./class/".$classname.".class.php";     if (is_file($file

学习使用register定义变量的方法。

#include <stdio.h>int main(){register int i;int tmp=0;for(i=1;i<=100;i++)tmp+=i;printf("the sum is %d\n",tmp);return 0;}

视频: 千重浪Linux系统调试技术培训 03-01_Basic-CPU-Register

免费轻松学习Linux系统调试技术   欢迎收看本工作室放到优酷上播放的免费教学视频。   清晰! 完整!  无病毒!   请点击:http://v.youku.com/v_show/id_XNjM1OTQ3MjY0.html