Как сделать переменную pu sh в встроенной сборке sd cc? - PullRequest
0 голосов
/ 12 января 2020

У меня есть этот код в ThreadCreate():

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

Это приводит к:

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

Я не понимаю, почему. tmpPSW четко определено, но sd cc жалуется. Что я здесь не так делаю? Есть ли другой способ использовать переменную pu sh C во встроенной сборке sd cc?

Также это, вероятно, актуально. Сгенерированный файл .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

1 Ответ

1 голос
/ 12 января 2020

Компилятор оптимизировал вашу переменную, потому что она никогда не использовалась с точки зрения компилятора. Сравните сгенерированную сборку с источником, чтобы увидеть это.

Вы можете попробовать другие варианты. Поскольку у меня не установлена ​​SD CC, я могу просто предложить:

  • Сделать переменную volatile.
  • Сделать переменную static, так как один flavour из PUSH работает с адресом во внутренней памяти.
  • Поскольку встроенная сборка сильно зависит от окружающего кода и компилятора, вы также можете использовать newThID в сборочной части, и сделайте там сдвиг.

Примечание 1. Сгенерированная сборка демонстрирует, насколько медленным становится машинный код, если вы используете int, не задумываясь. Ограничьте ваши переменные наименьшим подходящим типом данных.

Примечание 2. Не делайте переменную глобальной. static делает то, что вы хотите, не выставляя переменную глобально: поместите ее в оперативную память, чтобы к ней можно было получить доступ.

...