找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2421|回复: 17
打印 上一主题 下一主题
收起左侧

请问关于单片机C语言寻址方式与汇编语言栈的问题

[复制链接]
跳转到指定楼层
楼主
一:请问一下c语言寻址方式有几种,以怎样的语句流程实现以下的需求的
1:  80H地址 = FFEFH地址的值+P1端口的值       80H=FFEFH+P1         用c语言如何表达



2:  80H地址 =变量 A的值+P1端口的值
         80H = A+P1           用c语言如何表达

3: 80H地址 =变量 A的值+0x35
         80H = A+0x35        用c语言如何表达

4: 80H地址 =数字0x35+数字0x35
       80H =0x35+0x35      用c语言如何表达

二:请问关于“用栈传递参数”这个词语。我写汇编程序的时候,也尝试用 push  pop给地址赋值,但是用mov指令也可以达到
       将80h的值赋给81h    mov 81h,80h        
                               push 81h
                               push 80h
                               pop 81h
                               pop 80h         还是栈传递参数比mov指令有特殊的意义
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:883242 发表于 2023-4-11 20:55 | 只看该作者
1)前面4个问题你没有说明80H位于哪个空间?是idata、pdata还是xdata,所以无法回答。

2)堆栈传递函数是标准c语言的做法,但是c51不是标准c语言,8051这个内核太弱了用标准c语言实现过于浪费资源,所以你的问题无意义。
回复

使用道具 举报

板凳
ID:69038 发表于 2023-4-11 21:34 | 只看该作者
我记得用MOV会改变C和DC位,而PUSH、POP则不会。
回复

使用道具 举报

地板
ID:883242 发表于 2023-4-12 01:13 | 只看该作者
zhuls 发表于 2023-4-11 21:34
我记得用MOV会改变C和DC位,而PUSH、POP则不会。

通过ACC的MOV当然会改变PSW标志位,然而mov 81h,80h这个不通过ACC的指令???
注:mov 81h,80h这句话也是错的,指令本身没问题,后面的两个操作数大于7fh在逻辑上错了。
回复

使用道具 举报

5#
ID:73992 发表于 2023-4-12 07:06 来自手机 | 只看该作者
Hephaestus 发表于 2023-4-11 20:55
1)前面4个问题你没有说明80H位于哪个空间?是idata、pdata还是xdata,所以无法回答。

2)堆栈传递函数 ...

80h是指用@R0,或者@R1 访问的那个128字节地址
回复

使用道具 举报

6#
ID:69038 发表于 2023-4-12 08:46 | 只看该作者
Hephaestus 发表于 2023-4-12 01:13
通过ACC的MOV当然会改变PSW标志位,然而mov 81h,80h这个不通过ACC的指令???
注:mov 81h,80h这句话也 ...

不是很懂毕竟没有系统地学过,就是在翻书时看到的
回复

使用道具 举报

7#
ID:624769 发表于 2023-4-12 16:23 | 只看该作者
你的问题,必须汇编 和 C 都懂得才能回答,但是,你的描述,又非常的不确切,让人无从切入,不如你先把你一 当中的问题用汇编表述出来,然后,再跟你讲 C 里面如果实现吧。

先回答你  二的问题。
MOV   81H,80H
是把  81H地址的值  赋值到 80H地址, 最终的结果,是81H 和 80H 地址的 内容 完全相等。

而,
PUSH 81H
PUSH 80H
POP 81H
POP 80H
是把  81H  和  80H  两个地址的 内容互相交换,最终  81H 地址的内容 为原  80H地址的内容,而80H 地址的内容为原81地址的内容,要达到这个目的,不使用堆栈的话,不能简单地用MOV 要用如下指令:
XCH  A,80H
XCH  A,81H
XCH  A,80H
这个最终结果和通过堆栈 交换数据的结果是一样的。效率也要高一点,所以,用堆栈交换数据,实际没有太大的意义。
回复

使用道具 举报

8#
ID:73992 发表于 2023-4-12 17:13 | 只看该作者
188610329 发表于 2023-4-12 16:23
你的问题,必须汇编 和 C 都懂得才能回答,但是,你的描述,又非常的不确切,让人无从切入,不如你先把你一 ...

第一个问题,是想知道c语言对 80h地址 片外地址 端口p1  变量 的值 立即数 的语句流程
1:MOV
      MOV DPTR,#FFEFH
     MOV A,@DPTR
     
     
回复

使用道具 举报

9#
ID:883242 发表于 2023-4-12 17:19 | 只看该作者
lyonkon 发表于 2023-4-12 07:06
80h是指用@R0,或者@R1 访问的那个128字节地址

那你声明变量的时候加个idata修饰就可以了,指定80h地址毫无意义。
回复

使用道具 举报

10#
ID:73992 发表于 2023-4-12 17:25 | 只看该作者
188610329 发表于 2023-4-12 16:23
你的问题,必须汇编 和 C 都懂得才能回答,但是,你的描述,又非常的不确切,让人无从切入,不如你先把你一 ...

1:MOV R0,#80H
  MOV DPTR,#FFEFH
   MOV A,@DPTR
   ADD A,P1
   MOV @R0,A
我主要想知道,c语言片内,片外,寻址语句方式流程。并且运算的时候是不是先将地址中的值取到变量再计算。
回复

使用道具 举报

11#
ID:883242 发表于 2023-4-12 17:38 | 只看该作者
lyonkon 发表于 2023-4-12 17:25
1:MOV R0,#80H
  MOV DPTR,#FFEFH
   MOV A,@DPTR

片内0~7fh是data(可以不写),80h以上要加idata修饰,片外用pdata或者xdata修饰,如果你真的懂了汇编应该能马上理解pdata和xdata的区别。
回复

使用道具 举报

12#
ID:624769 发表于 2023-4-12 20:35 | 只看该作者
lyonkon 发表于 2023-4-12 17:25
1:MOV R0,#80H
  MOV DPTR,#FFEFH
   MOV A,@DPTR

方法一:
unsigned char idata *pd;
unsigned char xdata *px;
pd = 0x80;
px = 0xffef;
*pd = *px + P1;

方法二:
unsigned char idata temp1 _at_ 0x80;
unsigned char xdata temp2 _at_ 0xffef;
temp1 = temp2 + P1;

方法三:
*((unsigned char idata *)0x80) = *((unsigned char xdata *)0xffef) + P1;

以上三个方法,均可达到你汇编代码的目的,至于到底该用哪种方法,随着你C语言学习的深入,自己会有决断。
回复

使用道具 举报

13#
ID:73992 发表于 2023-4-12 21:26 | 只看该作者
188610329 发表于 2023-4-12 20:35
方法一:
unsigned char idata *pd;
unsigned char xdata *px;

依据您的例程,以下是我理解。c语言的寻址方式是通过声明地址变量,进行间接寻址。类似与@RI,和@dptr。  *pd = *px + P1;可以以间接寻址的形式,参与运算表达式。
非常感谢您的解答,我应该理解了。
回复

使用道具 举报

14#
ID:1065084 发表于 2023-4-13 09:21 | 只看该作者
lyonkon 发表于 2023-4-12 21:26
依据您的例程,以下是我理解。c语言的寻址方式是通过声明地址变量,进行间接寻址。类似与@RI,和@dptr。  ...

汇编语言直接对应机器码,机器码的重点是针对不同的机器乃至不同的型号操作都是不同的。

例如你用汇编访问寄存器,你是以寄存器的实际地址来访问的,而且就简单的MOV指令就分为MOV、MOVC、MOVX,在C中是没有这三种MOV指令的区别,乃至你换到其他架构系统也是直接转移的,而你的汇编程序要全部重写一遍。

所谓的高级语言就是通用性更强,适配性更强。比如你用c在51 和32之间转换使用,只说算法层面不说外设,你只需要把例如int等数据变量重新调整一下。

你强制让c去访问固定地址,编程上是可以的,但是没有意义,因为对于数据来说存无论存储在20H还是21H都是一样的,可能你说,不知道地址怎么行,存储器用满了怎么办?编译器:不用在意我,我会出手。编译器在编译时会自动检测剩余内存和其他资源以及错误,所以,不要担心

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

15#
ID:883242 发表于 2023-4-13 12:18 | 只看该作者
yuxuesuixing 发表于 2023-4-13 09:21
汇编语言直接对应机器码,机器码的重点是针对不同的机器乃至不同的型号操作都是不同的。

例如你用汇编 ...

标准c当然不区分,但是C51会区分这三种指令。
MOV对应data(默认,可以不写),idata和SFR空间
MOVC对应code空间
MOVX对应pdata和xdata空间

高级语言通用性强,但是死忒惨这个螺蛳壳里面很难做道场的,所以C51没有通用性。
回复

使用道具 举报

16#
ID:73992 发表于 2024-2-20 17:45 | 只看该作者
谢谢各位朋友的解答。
直到现在才有能力描述这个问题,当时是想模仿c语言写一套通用的命令子程序集,写程序时候可以随意调。因为不知道具体需要什么功,就相当于没找到需求就搁置了。不曾想现在有了需求;


上面这个程序,因为R0,R1,在子程序中要使用,没有剩下其他寄存器可用 R0,R1,又无法入,将R0,R1先写入内存 当栈使用妥协办法。

下面这个程序,将相同功能的程序写了两遍,刷两个固化值。因为只使用一次,所以偷点懒感觉没有问题。



现在的问题是,调用子程  要传递值进去,然后子程序执行完了结果还要留着。目前我是使用以下方法,
使用内存传递值。请老师指点一下。




回复

使用道具 举报

17#
ID:883242 发表于 2024-2-20 18:03 | 只看该作者
R0、R1一共有4组,用register bank区分,可以不需要压栈保护。楼主从去年就开始搞cortex-M和51汇编,为什么到现在还没有入门?
回复

使用道具 举报

18#
ID:73992 发表于 2024-2-20 22:27 | 只看该作者
Hephaestus 发表于 2024-2-20 18:03
R0、R1一共有4组,用register bank区分,可以不需要压栈保护。楼主从去年就开始搞cortex-M和51汇编,为什么 ...

这样可以将相同性质的数据放在一个寄存器页面。谢谢!
一直在调试stm32硬件,过程中汇编程序不复杂。硬件现在调试差不多了。着手写复杂点程序的时候,发现了问题。程序之间数据传递,我一直都是放在指定内存中使用的。我觉得这样可能不规范,所以想规范一下。相当于汇编语言现在才开始学。
如果是arm内核,里面R0--R15只有一个页面,程序之间传递数据
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表