单片机中跳转指令偏移量如何计算?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机中跳转指令偏移量如何计算?相关的知识,希望对你有一定的参考价值。
MOVC A,@A+DPTR;偏移量的计算只要将INC A;加一指令,将累加器A的数据加一就可改变(因为查表指令是查数据,数据是单字节的,所以加一即可)。例如:TAB:DB 30H,55H,83H;TAB是表头,DB是列表的意思。如果上述中累加器@A=00H,则查表指令后,A就等于30H。如累加器@A等于02H,查表指令后,A等于83H。就是说改变@A的偏移量就可查出对应的数值。@A=00H时查出的数据是30H,@A=01H时查出的数据是55H,@A=02H时查出的是83H,其他的我想你应该会推算了吧 参考技术A 单片机中地址偏移值,准确来说应叫做:偏移量用rel表示,是一个8位的带符号数(即补码);表示数的范围为 -128~127;
比如:基址是0x1000,而0x1002就相对0x1000偏移了2;
MOVC A,@A+DPTR;偏移量的计算只要将INC A;加一指令,将累加器A的数据加一就可改变。 参考技术B 跳转指令中直接使用地址名就行,不用计算偏移量,比如
AJMP HERE
...
HERE:MOV A,#0
...
如果数组大小发生变化以及定义的宏如何在此处计算偏移量,为啥 C 结构中的字符数组的偏移量会有所不同? [复制]
【中文标题】如果数组大小发生变化以及定义的宏如何在此处计算偏移量,为啥 C 结构中的字符数组的偏移量会有所不同? [复制]【英文标题】:Why Offset varies for character array in C structure if array size changes and how the defined macro is calculating offset here? [duplicate]如果数组大小发生变化以及定义的宏如何在此处计算偏移量,为什么 C 结构中的字符数组的偏移量会有所不同? [复制] 【发布时间】:2021-05-21 18:03:32 【问题描述】:我已经定义了一个宏来计算结构到任何结构字段的偏移量。 代码如下:
#define offset(struct_name, fld_name) \
(unsigned int)&(((struct_name *)0)->fld_name)
typedef struct emp_
char name[20];
unsigned int salary;
char designation[30];
unsigned int emp_id;
emp_t;
int main(int argc, char **argv)
unsigned int offsetValue;
offsetValue=offset(emp_t,salary);
printf("field = %s\n","salary");
printf("offset = %d\n", offsetValue);
return 0;
如果我编译并运行代码,“salary”字段的偏移量是 20,它应该是 20。
但是,如果我将结构字段char name[20];
更改为char name[30];
,“salary”的偏移量将更改为 32,但它应该是 30。如果我进一步将结构字段更改为 char name[1];
,“salary”的偏移量将更改为 4,但它应该是 1. 为什么会出现这些偏移值差异?
问题的第二部分是#define offset
宏究竟是如何计算偏移量的? &(((struct_name *)0)->fld_name)
实际上在做什么?外面的&
表示地址,但剩下的(((struct_name *)0)->fld_name)
到底是什么意思?
【问题讨论】:
它会改变以成为 4 字节对齐(一个 int 的大小) 这不是你的问题,但没有必要定义宏——C在stdlib.h中定义offsetof
确实如此,谢谢@NateEldredge
您问题的第二部分已回答there。另见Wikipedia
【参考方案1】:
对于在您的系统中大小为 4 字节的 unsigned int
类型的对象使用对齐方式。 30 不能被 4 整除,所以在字符数组中追加了两个字节。
考虑以下演示程序。
#include <stdio.h>
int main(void)
printf( "sizeof( struct A ) = %zu\n", sizeof( struct A char c; int x; ) );
printf( "sizeof( struct B ) = %zu\n", sizeof( struct B char c; double d; ) );
return 0;
它的输出是
sizeof( struct A ) = 8
sizeof( struct B ) = 16
int
类型的大小等于4
,double
类型等于8
。因此,struct A 类型的对象应由可被 4 整除的边界对齐,而 struct B 的对象应由可被 8 整除的边界对齐。
例如,您可以使用编译器指令打包结构。但在这种情况下,对此类结构的数据成员的访问效率会很低。
【讨论】:
以上是关于单片机中跳转指令偏移量如何计算?的主要内容,如果未能解决你的问题,请参考以下文章