求一个单片机的编程题

2025-01-05 22:13:06
推荐回答(3个)
回答1:

用汇编比较简单,可以直接寻址。MOV A,30H,再判断正负,正数:MOV 40H,A;负数:MOV 50H,A。
用C的话,先定义指针指向30H,40H及50H的单元,比如
char *pi=0x0030;char *zheng=0x0040;char *fu=0x0050;char i=0;
while(i<10) //再判断正负
{
if(*(pi+i)&0x80!=0)
*(zheng++)=*(pi+i); //正数依次放入40h中
else
*(fu++)=*(pi+i); //负数依次放入50h中
i++;
}
汗,不知不觉写出来了,本来只是想提示一下。。。
判断方法:首先负数在内存中存储的是补码,这样我们就可以直接判断第7位是否为1,为1表示该RAM里存的是负数,反之则为正数。

回答2:

ORG 0000H
SJMP MAIN
ORG 0040H
MAIN:MOV R2,#40H ;R2用作计量正数的地址
MOV R3,#50H ;R3用作计量负数的地址
MOV R0,#30H ;R0用作计量数组的地址
LP4: CJNE @R0,#00H,LP0 ;这十个数中为零的数,不存储,接着判断下一个数
SJMP LP1
LP0:MOV 22H,@R0 ;不为零的数放在内存地址为22H的单元中,通过判断最高位来判断正负
JB 17H,LP2 ;如果最高位为1,则为负数,在LP2程序段中把负数依次存储;
SJMP LP3 ;如果最高位为0,则为正数,在LP3程序段中把正数依次存储。
LP2:MOV A,R3
MOV R1,A
MOV @R1,22H
INC R3 ;存取负数的单元地址依次加一
SJMP LP1
LP3:MOV A,R2
MOV R1,A
MOV @R1,22H
INC R2 ;存取正数的单元地址依次加一
LP1:INC R0 ;存放数组的单元地址依次加一
CJNE R0,#3AH,LP4
END

回答3:

现假定左边是地址,右边的是内容
1.它的功能是以50H为首地址,个数为0AH个的RAM全部清零

2.机器码
7A 0A··········MOV R2,#0AH
mov rn的机器码是01111xxx,其中xxx由Rn的地址来决定,相应地,R0~R7二进制地址为000~111
那么R2就是010,后面的数据就跟着mov rn的机器码后面

7850··········MOV R0,#50H
E4 ···········CLR A;
机器码固定
F6 ·········LOOP:MOV @R0,A

mov @rn,a机器码为1111011n
n就是Rn的n
所以间接寄存器寻址只能是R1或R0

08 ············INC R0
inc rn机器码为00001xxx
xxx同理为Rn的物理地址

DA__ ···········DJNZ R2,LOOP
djnz rn机器码11011xxx
xxx同理为RN的物理地址
loop为8位地址标号
机器码是以loop为首的第一个指令离loop的单元数
所以djnz r2,loop的loop不能放在此后超过255字节的程序空间单元
题中loop:后面跟有MOV @R0,A占1个内部ram单元,INC R0占1个内部ram单元,DJNZ R2占1个内部ram单元(由机器码可得),所以255-3=252=FCH
即机器码为DAFC

···········DONE:

3.对于第三个问题,楼上的方法有误
,R0和R2有可能在00H~A0H
而且你只是把0~10放入50H~5AH单元
所以可以这样
SETB RS1
SETB RS0;R0工作在18H单元
MOV A,#50H
MOV R2,#10
MOV R0,#0
LOOP:
MOV @R0,A
INC A
INC R0
DJNZ R2,LOOP

经仿真无误