Pointers 高速机箱构造汇编程序+加载DPTR fast-8051

Pointers 高速机箱构造汇编程序+加载DPTR fast-8051,pointers,assembly,switch-statement,8051,jump-table,Pointers,Assembly,Switch Statement,8051,Jump Table,我目前正在为8051 IC特别是AT89C4051实现一个串行例程,我没有太多的堆栈空间或内存,为了在串行端口38K或更高的波特率上实现一个合适的波特率,我需要进行高速case构造,因为在我的串行端口中断例程中,我正在建立一个包并检查它的有效性 假设我们在串行中断中,R0是要接收数据的内存空间的地址。假设起始地址是40h 下面我们来做一系列比较: 通过多个比较进行分支 上面的代码一开始可能是实用的,但随着要处理的数据包中当前字节的增加,由于额外的cjne指令处理,例程每次运行慢2个时钟周期。例如

我目前正在为8051 IC特别是AT89C4051实现一个串行例程,我没有太多的堆栈空间或内存,为了在串行端口38K或更高的波特率上实现一个合适的波特率,我需要进行高速case构造,因为在我的串行端口中断例程中,我正在建立一个包并检查它的有效性

假设我们在串行中断中,R0是要接收数据的内存空间的地址。假设起始地址是40h

下面我们来做一系列比较:

通过多个比较进行分支

上面的代码一开始可能是实用的,但随着要处理的数据包中当前字节的增加,由于额外的cjne指令处理,例程每次运行慢2个时钟周期。例如,如果我们在第7个字节,那么cjne会发生很多次,因为它必须扫描每一个案例,这会增加慢度

通过跳转分支

现在我想只使用跳转,但我不知道如何高速加载DPTR,因为即使其他进程使用DPTR的值,也可以调用中断

我想到了这个代码:

serial:
    mov A,SBUF
    mov @R0,A
    mov A,R0
    anl A,#07h ;our packet is 8 bytes so get current packet # based on what we stored so far
    swap A ;multiply A times 16 and
    rr A ;divide A by 2 so we get address times 8 since each block uses 8 bytes of code space.

    mov R3,DPH ;save DPTR high byte without breaking stack
    mov R6,DPL ;save DPTR low byte
    mov dptr,#table
    jmp @A+DPTR
    theend:
    mov DPL,R6 ;restore DPTR low byte
    mov DPH,R3 ;restore DPTR high byte
    inc R0     ;move on to next position
reti
table:
;insert 8 bytes worth of code for 1st case
;insert 8 bytes worth of code for 2nd case
;insert 8 bytes worth of code for 3rd case
...
;insert unlimited bytes worth of code for last case
在我的代码中,R3和R6是自由的,所以我使用它们来存储旧的DPTR值,但是那些mov指令以及加载新的DPTR值需要每个2个周期,总共10个周期,包括恢复旧值


是否有一种更快的方法来处理8051汇编代码中的case构造,以便我的串行例程处理得更快?

如果可能,不要在ISR中运行逻辑。如果您坚持,您可能能够将DPTR分配给ISR,并且只在禁用中断的非常短的正常代码段中使用它。或者,推+再推技巧也可以奏效

这里是一种链式方法,每个处理过的字符只为下一步设置地址。如果可以确保步骤在相同的256字节块内,则只需更新低位字节。总的开销是8个周期,但您也为算术节省了4个周期,因此这是6个周期的胜利

.EQU PTR, 0x20  ; two bytes of SRAM

; Initialize PTR to address of step1 

serial:
    push PTR
    push PTR+1
    ret

step1:
    ; do stuff
    mov PTR, #low8(step2)
    reti

last_step:
    ; do stuff
    mov PTR, #low8(step1)
    reti
.EQU PTR, 0x20  ; two bytes of SRAM

; Initialize PTR to address of step1 

serial:
    push PTR
    push PTR+1
    ret

step1:
    ; do stuff
    mov PTR, #low8(step2)
    reti

last_step:
    ; do stuff
    mov PTR, #low8(step1)
    reti