0

我有这个代码ThreadCreate()

int tmpPSW = newThID << 3;
__asm
    PUSH A
    PUSH _tmpPSW
__endasm;

这导致:

?ASlink-Warning-Undefined Global '_tmpPSW' referenced by module 'cooperative'

我不明白为什么。tmpPSW定义明确,但 sdcc 抱怨。我在这里做错了什么?还有其他方法可以在 sdcc 内联汇编中推送 C 变量吗?

这也可能是相关的。生成的.asm文件包含分配信息:

;------------------------------------------------------------
;Allocation info for local variables in function 'ThreadCreate'
;------------------------------------------------------------
;fp                        Allocated to registers 
;newThMask                 Allocated to registers r6 r7 
;newThID                   Allocated to registers r5 
;startSP                   Allocated to registers r3 r4 
;tmp                       Allocated to registers 
;tmpPSW                    Allocated to registers 
;------------------------------------------------------------

这是否意味着我的寄存器用完了?如果是这样,我应该如何减轻这种情况?


编辑:

来源ThreadCreate()

// ThreadID is typedef&#039;ed as char
ThreadID ThreadCreate(FunctionPtr fp) {
    if (activeTh == 0b1111)
        return -1;

    // i.e. get rightmost bit 0 in bitmask
    // https://stackoverflow.com/a/42747608/6306190
    int newThMask = ~activeTh & (activeTh + 1);

    activeTh |= newThMask;

    ThreadID newThID = 0;
    while (newThMask >>= 1) { newThID++; }
    int startSP = (newThID ^ (1UL << 2)) << 4;

    int tmp = SP;
    SP = startSP;

    int tmpPSW = newThID << 3;
    __asm
        PUSH DPL          ;; push _fp (argument passed in as DPTR in SDCC)
        PUSH DPH          ;; push _fp
        MOV A, #0
        PUSH A            ;; ACC
        PUSH A            ;; B
        PUSH A            ;; DPL
        PUSH A            ;; DPH
        PUSH _tmpPSW      ;; PSW
    __endasm;

    savedSP[newThID] = SP;
    SP = tmp;
    return newThID;
}

生成的程序集ThreadCreate()

;------------------------------------------------------------
;Allocation info for local variables in function &#039;ThreadCreate&#039;
;------------------------------------------------------------
;fp                        Allocated to registers 
;newThMask                 Allocated to registers r6 r7 
;newThID                   Allocated to registers r5 
;startSP                   Allocated to registers r3 r4 
;tmp                       Allocated to registers 
;tmpPSW                    Allocated to registers 
;------------------------------------------------------------
;   cooperative.c:104: ThreadID ThreadCreate(FunctionPtr fp) {
;   -----------------------------------------
;    function ThreadCreate
;   -----------------------------------------
_ThreadCreate:
;   cooperative.c:110: if (activeTh == 0b1111)
    mov a,#0x0f
    cjne    a,_activeTh,00121$
    clr a
    cjne    a,(_activeTh + 1),00121$
    sjmp    00122$
00121$:
    sjmp    00102$
00122$:
;   cooperative.c:111: return -1;
    mov dpl,#0xff
    ret
00102$:
;   cooperative.c:119: int newThMask = ~activeTh & (activeTh + 1);
    mov a,_activeTh
    cpl a
    mov r6,a
    mov a,(_activeTh + 1)
    cpl a
    mov r7,a
    mov a,#0x01
    add a,_activeTh
    mov r4,a
    clr a
    addc    a,(_activeTh + 1)
    mov r5,a
    mov a,r4
    anl ar6,a
    mov a,r5
    anl ar7,a
;   cooperative.c:157: activeTh |= newThMask;
    mov a,r6
    orl _activeTh,a
    mov a,r7
    orl (_activeTh + 1),a
;   cooperative.c:160: while (newThMask >>= 1) { newThID++; }
    mov r5,#0x00
00103$:
    mov ar3,r6
    mov a,r7
    mov c,acc.7
    rrc a
    xch a,r3
    rrc a
    xch a,r3
    mov r4,a
    mov ar6,r3
    mov ar7,r4
    mov a,r3
    orl a,r4
    jz  00105$
    inc r5
    sjmp    00103$
00105$:
;   cooperative.c:161: int startSP = (newThID ^ (1UL << 2)) << 4;
    mov ar3,r5
    mov r4,#0x00
    mov r6,#0x00
    xrl ar3,#0x04
    mov a,r4
    swap    a
    anl a,#0xf0
    xch a,r3
    swap    a
    xch a,r3
    xrl a,r3
    xch a,r3
    anl a,#0xf0
    xch a,r3
    xrl a,r3
    mov r4,a
;   cooperative.c:163: int tmp = SP;
    mov r7,_SP
;   cooperative.c:164: SP = startSP;
    mov _SP,r3
;   cooperative.c:176: __endasm;
    PUSH    DPL ;; push _fp (argument passed in as DPTR in 390)
    PUSH    DPH ;; push _fp
    MOV A, #0
    PUSH    A ;; ACC
    PUSH    A ;; B
    PUSH    A ;; DPL
    PUSH    A ;; DPH
    PUSH    _tmpPSW ;; PSW
;   cooperative.c:178: savedSP[newThID] = SP;
    mov a,r5
    add a,r5
    add a,#_savedSP
    mov r1,a
    mov r4,_SP
    mov r6,#0x00
    mov @r1,ar4
    inc r1
    mov @r1,ar6
;   cooperative.c:179: SP = tmp;
    mov _SP,r7
;   cooperative.c:180: return newThID;
    mov dpl,r5
;   cooperative.c:181: }
    ret
4

1 回答 1

1

编译器优化了您的变量,因为从编译器的角度来看,它从未使用过。将生成的程序集与源代码进行比较以查看这一点。

您可以尝试其他选项。因为我没有安装 SDCC,我只能建议:

  • 使变量volatile.
  • 制作变量static,因为其中一种方式PUSH适用于内部 RAM 中的地址。
  • 因为内联汇编在很大程度上取决于周围的代码和编译器,所以您也可以newThID在汇编部分使用,并在那里进行转换。

注 1:生成的程序集演示了如果您int不加思索地使用机器代码会变得多么慢。将变量限制为最小的适当数据类型。

注意 2:不要将变量设为全局变量。static在不全局公开变量的情况下执行您想要的操作:将其放在 RAM 中,以便可以访问它。

于 2020-01-12T17:17:42.103 回答