Отговори на тема  [ 13 мнения ] 
асемблер за 8051 ядро 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Авг 31, 2005 1:57 pm
Мнения: 1103
Мнение асемблер за 8051 ядро
Здравейте, вече питах няколко участника във форума за помощ, но никой не се отзова.
По въпроса имам сорс код на асемблер за процесор от преди 20 години. Бих искал да попреведа на С част от кода за да ми станат ясни някои алгоритми. С асемблер за 8051 не съм работил никога (имам опит само с PIC) и ще ми отнеме много време.
Ето пример, ако някой удари едно рамо ще съм много благодарен

tss_aa:

mov a,x_minu
mov b,#60
mul ab
add a,x_secu
push acc
jnc tss_a
inc b
tss_a: push b

mov b,#5

mov a,time_p1
jb acc.7,tss_b
mul ab
sjmp tss_e
tss_b:
mov a,w_minu ;lade ewz
mov b,#60
mul ab
mov dpl,a
mov dph,b

mov a,time_p1
cpl a
inc a
mov b,#5
mul ab
add a,time_ramp
jnc tss_c
inc b
tss_c:
call subdp
jnc tss_d
pop dph
pop dpl
clr c
setb ov
sjmp tss_p2

tss_d:
mov a,dpl
mov b,dph

tss_e:
pop dph
pop dpl ;

call subdp
jc tss_p1

setb ov
mov a,dph
jnz tss_p2
mov a,dpl
cjne a,time_ramp,tss_f


Пон Окт 09, 2023 10:11 am
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 25, 2012 9:14 am
Мнения: 5298
Мнение Re: асемблер за 8051 ядро
Идея - чатгпт. Аз му дадох това парче код и ми върна ето това:

Код:
void tss_aa() {
    unsigned char a, b;
    unsigned int result;

    a = x_minu;
    b = 60;
    result = a * b + x_secu;
    push(result & 0xFF);

    if (!(result & 0x100)) {
        b++;
    }
    push(b);

    b = 5;
   
    if (!(time_p1 & 0x80)) {
        result = w_minu * 60;
        dpl = result & 0xFF;
        dph = result >> 8;
    }
    else {
        a = ~time_p1 + 1;
        a++;
        result = a * 5 + time_ramp;
        if (!(result & 0x100)) {
            b++;
        }
        subdp();
        if (c) {
            pop(&dph);
            pop(&dpl);
            c = 0;
            ov = 1;
            goto tss_p2;
        }
    }

    tss_d:
    dpl = a;
    dph = b;

    tss_e:
    pop(&dph);
    pop(&dpl);
    subdp();
    if (c) {
        tss_p1:
        ov = 1;
        if (dph != 0) {
            goto tss_p2;
        }
        else {
            if (dpl != time_ramp) {
                tss_f();
            }
        }
    }

    tss_p2:
    // Continue your code here.
}


_________________
'просто' е технически синоним на 'красиво'


Пон Окт 09, 2023 11:16 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: асемблер за 8051 ядро
Бабане, то това е буквално превод на всяка асм инструкция на Ц - няма много мисъл кое какво точно прави ... особенно там с inc() като има Carry - т.е. 16 битово събиране с пренос направено с примитивни 8 битови инструкции

_________________
Мразя да мразя ...


Пон Окт 09, 2023 12:46 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 25, 2012 9:14 am
Мнения: 5298
Мнение Re: асемблер за 8051 ядро
Сега ще го пробвам за бейсик :)

_________________
'просто' е технически синоним на 'красиво'


Пон Окт 09, 2023 1:09 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 25, 2012 9:14 am
Мнения: 5298
Мнение Re: асемблер за 8051 ядро
:D :D

Код:
' Define a subroutine named tss_aa
Sub tss_aa
    ' Move the value of x_minu to variable a
    a = x_minu
    ' Load b with the value 60
    b = 60
    ' Multiply a and b, result in acc (accumulator)
    acc = a * b
    ' Add the value of x_secu to acc
    acc = acc + x_secu
    ' Push the value of acc onto the stack
    Push acc
    ' Jump if no carry (jnc) to tss_a
    If Not CarryFlag Then Goto tss_a
    ' Increment b
    b = b + 1
tss_a:
    ' Push the value of b onto the stack
    Push b
    ' Load b with the value 5
    b = 5
    ' Load a with the value of time_p1
    a = time_p1
    ' Jump if bit 7 of acc is set (jb acc.7) to tss_b
    If Bit7(a) Then Goto tss_b
    ' Multiply a and b, result in acc
    acc = a * b
    ' Unconditional jump (sjmp) to tss_e
    Goto tss_e
tss_b:
    ' Load a with the value of w_minu
    a = w_minu
    ' Load b with the value 60
    b = 60
    ' Multiply a and b, result in acc
    acc = a * b
    ' Move the result to dpl (data pointer low)
    dpl = a
    ' Move b to dph (data pointer high)
    dph = b

    ' Load a with the value of time_p1
    a = time_p1
    ' Complement (cpl) a
    a = Not a
    ' Increment a
    a = a + 1
    ' Load b with the value 5
    b = 5
    ' Multiply a and b, result in acc
    acc = a * b
    ' Add the value of time_ramp to acc
    acc = acc + time_ramp
    ' Jump if no carry (jnc) to tss_c
    If Not CarryFlag Then Goto tss_c
    ' Increment b
    b = b + 1
tss_c:
    ' Call the subroutine subdp
    Call subdp
    ' Jump if no carry (jnc) to tss_d
    If Not CarryFlag Then Goto tss_d
    ' Pop the values from the stack into dph and dpl
    Pop dph
    Pop dpl
    ' Clear the carry flag
    CarryFlag = False
    ' Set the overflow flag
    OverflowFlag = True
    ' Unconditional jump (sjmp) to tss_p2
    Goto tss_p2
tss_d:
    ' Move the values of dpl and dph to a and b
    a = dpl
    b = dph

tss_e:
    ' Pop the values from the stack into dph and dpl
    Pop dph
    Pop dpl
    ' Call the subroutine subdp
    Call subdp
    ' Jump if carry (jc) to tss_p1
    If CarryFlag Then Goto tss_p1

    ' Set the overflow flag
    OverflowFlag = True
    ' Move the value of dph to a
    a = dph
    ' Jump if not zero (jnz) to tss_p2
    If a <> 0 Then Goto tss_p2
    ' Move the value of dpl to a
    a = dpl
    ' Compare a and time_ramp, and jump to tss_f if not equal
    If a <> time_ramp Then Goto tss_f


_________________
'просто' е технически синоним на 'красиво'


Пон Окт 09, 2023 1:10 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Ное 06, 2018 5:18 pm
Мнения: 1750
Мнение Re: асемблер за 8051 ядро
Ето го и моят ChatGPT (версия 4) какво казва по въпроса:
Цитат:
Код:
#include <stdint.h>

// Assuming these are global variables or registers
uint8_t x_minu, x_secu, time_p1, w_minu, time_ramp;

// We'll create a struct to mimic the 8051's DPTR 16-bit register pair (DPL and DPH)
typedef struct {
    uint8_t low;
    uint8_t high;
} dptr_t;

dptr_t dptr; // our representation of DPTR

// We'll assume that subdp() is a function that subtracts dptr from another 16-bit value
// and then sets some global flags, like CY (carry) and OV (overflow).
// These are just placeholders; you'd need to implement them based on your requirements.
uint8_t CY = 0; // carry flag
uint8_t OV = 0; // overflow flag

void subdp(void) {
    // Placeholder; implement the required subtraction logic here
}

void tss_aa() {
    uint16_t temp_result;
    uint8_t tmp_acc;
    uint8_t tmp_b;

    temp_result = x_minu * 60;
    tmp_acc = (uint8_t)(temp_result & 0x00FF); // lower byte
    tmp_b = (uint8_t)((temp_result & 0xFF00) >> 8); // higher byte

    tmp_acc += x_secu;

    if (tmp_acc < x_secu) { // check for overflow, equivalent to JNC in assembly
        tmp_b++;
    }

    dptr.low = tmp_b; // push onto our "stack"
    dptr.high = tmp_acc;

    if (time_p1 & 0x80) {
        // In this branch, the result of the multiplication is discarded.
        // It appears to be redundant in the original code.
        tmp_acc = time_p1 * 5;
    } else {
        temp_result = w_minu * 60;
        dptr.low = (uint8_t)(temp_result & 0x00FF);
        dptr.high = (uint8_t)((temp_result & 0xFF00) >> 8);

        tmp_acc = ~time_p1 + 1;
        temp_result = tmp_acc * 5 + time_ramp;

        tmp_acc = (uint8_t)(temp_result & 0x00FF);
        tmp_b = (uint8_t)((temp_result & 0xFF00) >> 8);

        subdp();

        if (!CY) {
            dptr.low = tmp_acc;
            dptr.high = tmp_b;
            OV = 1;
            return; // assumes sjmp tss_p2 is jumping out of this routine
        }

        tmp_acc = dptr.low;
        tmp_b = dptr.high;
    }

    subdp();

    if (CY) {
        OV = 1;
        if (dptr.high != 0 || dptr.low != time_ramp) {
            // Jump to tss_f, but this is not provided in the original code.
            // Insert the logic for tss_f here or call the tss_f function.
        }
    }
}

// If tss_p2 or tss_f are other functions or parts of the logic, they need to be implemented separately.


Note: The subdp function and the flags CY and OV are placeholders. The actual logic behind the subdp function and how the flags are managed need to be implemented based on your requirements. The above translation assumes certain behavior, and you might need to adjust it based on the real behavior of your program.

Както какзва чата функцията subdp липсва в асемблерския код, както и някои флагове. Най добре автора да направи обратно асемблиране за да види дали се генерира същия асемблер.

_________________
“Intelligence is the ability to adapt to change.” Stephen Hawking


Пон Окт 09, 2023 1:26 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: асемблер за 8051 ядро
Код:
    temp_result = x_minu * 60;
    tmp_acc = (uint8_t)(temp_result & 0x00FF); // lower byte
    tmp_b = (uint8_t)((temp_result & 0xFF00) >> 8); // higher byte

    tmp_acc += x_secu;

    if (tmp_acc < x_secu) { // check for overflow, equivalent to JNC in assembly
        tmp_b++;
    }

означава
Код:
  uint16_t temp_result = x_minu * 60 + x_secu;

_________________
Мразя да мразя ...


Пон Окт 09, 2023 3:20 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: асемблер за 8051 ядро
Код:
    if (time_p1 & 0x80) {
        // In this branch, the result of the multiplication is discarded.
        // It appears to be redundant in the original code.
        tmp_acc = time_p1 * 5;
    } else {
        temp_result = w_minu * 60;
        dptr.low = (uint8_t)(temp_result & 0x00FF);
        dptr.high = (uint8_t)((temp_result & 0xFF00) >> 8);

        tmp_acc = ~time_p1 + 1;
        temp_result = tmp_acc * 5 + time_ramp;

        tmp_acc = (uint8_t)(temp_result & 0x00FF);
        tmp_b = (uint8_t)((temp_result & 0xFF00) >> 8);

        subdp();

        if (!CY) {
            dptr.low = tmp_acc;
            dptr.high = tmp_b;
            OV = 1;
            return; // assumes sjmp tss_p2 is jumping out of this routine
        }

        tmp_acc = dptr.low;
        tmp_b = dptr.high;
    }

най вероятно означава:
Код:
    time_p1 >= 0 ? 5 * time_p1: w_minu * 60 - (5 * (-time_p1)+ time_ramp)

Без повечко код и без да си напъвам мозъка кой знае колко не мога да кажа повече. Може и да бъркам, че и асемеблер и 8051 не съм пипал от 20-на години.

_________________
Мразя да мразя ...


Пон Окт 09, 2023 3:28 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Ное 06, 2018 5:18 pm
Мнения: 1750
Мнение Re: асемблер за 8051 ядро
palavrov написа:
Код:
    time_p1 >= 0 ? 5 * time_p1: w_minu * 60 - (5 * (-time_p1)+ time_ramp)



MISRA ще ти пише 2 най-малко в две категории.

_________________
“Intelligence is the ability to adapt to change.” Stephen Hawking


Пон Окт 09, 2023 7:16 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: асемблер за 8051 ядро
Bai Ui написа:
palavrov написа:
Код:
    time_p1 >= 0 ? 5 * time_p1: w_minu * 60 - (5 * (-time_p1)+ time_ramp)



MISRA ще ти пише 2 най-малко в две категории.

Е, че това е псевдокод, не претендира за коректност ... даже чупената ми клавиатура е изяла и ; ... още не съм я сменил ... не остава време да намеря правилния доставчик (в амазон я няма)

_________________
Мразя да мразя ...


Пон Окт 09, 2023 9:09 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Авг 31, 2005 1:57 pm
Мнения: 1103
Мнение Re: асемблер за 8051 ядро
CHATGpt се оказа наистина интересно. Досега никога не бях ползвал :D


tp4bit_1x:
mov r1,#1

tp4bit:
mov r3,a
mov a,r2
anl a,#0fh ;sicherheitshalber за да бъдем на сигурно място
jnz tp4b_a ;springe wenn 1...15
mov a,#16 ; 0--> 16
tp4b_a: mov r2,a

tp4b_b: ;**** schleife
mov a,r3 ;lade endewert
mov b,r2 ;lade TP-faktor

clr c
subb a,@r0 ;acc = EW - TP(k-1)
inc r0 ;zeige auf TP-rest
jc tp4b_n ;springe wenn Differenz neg.

;**** differenz ist pos. разликата е поз
;**** differenz durch Faktor teilen разделете разликата на фактор
div ab ;in b stand der Faktor b беше факторът
mov r4,a ;rette ganz. anteil in r4 запазете цяло. пропорция в r4

mov a,r2 ;lade faktor
xch a,b ;acc = rest / b = faktor

swap a ;acc = 16 * rest
rlc a ;C | acc = 32*rest
orl a,r2 ;addiere Faktor
rrc a ;acc = 16*rest + faktor/2

div ab
swap a ; r4 | acc = [ 1/f *[EW-TP(k-1)]]

;**** bilde neues TP (r0 zeigt auf TP-rest) формира нов TP (r0 сочи към TP-rest)
add a,@r0
mov @r0,a ;по-нова Rest
dec r0
mov a,r4
addc a,@r0
mov @r0,a ;нов TP

;**** schleife панделка
djnz r1,tp4b_b ;loop
ret

tp4b_n: ;**** differenz ist negativ --> bilde komplement ,dann divison, dann subtraktion разликата е отрицателна --> образувайте допълнение, след това разделете, след това извадете
cpl a
inc a ;acc = -acc

;**** differenz durch Faktor teilen разделете разликата на фактор
div ab ;in b stand der Faktor b беше факторът
mov r4,a ;rette ganz. anteil in r4 запазете цяло. пропорция в r4

mov a,r2 ;lade faktor
xch a,b ;acc = rest / b = faktor

swap a ;acc = 16 * rest
rlc a ;C | acc = 32*rest
orl a,r2 ;добавете Faktor
rrc a ;acc = 16*rest + faktor/2

div ab
swap a ; r4 | acc = - [ 1/f *[EW-TP(k-1)]]

;**** bilde neues TP (r4 | acc subtrahieren) (r0 zeigt auf TP-rest) формиране на нов TP (r4 | acc изваждане) (r0 точки към TP остатък)
mov b,a ;спаси acc in b
mov a,@r0
clr c
subb a,b
mov @r0,a ;по-нова Rest
dec r0
mov a,@r0
subb a,r4
mov @r0,a ;нов TP

;**** schleife панделка
djnz r1,tp4b_b ;loop
ret

След два дена размисъл предполагам че тези сума редове могат да се сведат до
нискочестотен филтър

void tp4bit_1x (float *TP_End_val,float *TP_Start_val, unsigned char F_faktor )
{ //*TP_End_val tova e EW (a)
//*TP_Start_val (r0)
// r1=1
// F_faktor - r2
float tmp;
if (F_faktor>15) {F_faktor=0;}

tmp=(*TP_End_val-*TP_Start_val)/F_faktor; // EW - TP(k-1)/F_faktor

&TP_Start_val=*TP_Start_val+tmp; // нова стойност на филтъра

}


Сря Окт 11, 2023 8:08 am
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Дек 14, 2004 1:31 pm
Мнения: 3849
Мнение Re: асемблер за 8051 ядро
Код:
Let's break down this code step by step.

### Initial Code Setup:
- `mov r1,#1`: This initializes the register r1 to the value 1, which is later used for a loop count.
 
### Label `tp4bit`:
This label seems to be the start of the main function.
- `mov r3,a`: Saves the accumulator's value in register r3.
- `mov a,r2`: Moves the value of register r2 to the accumulator.
- `anl a,#0fh`: Bitwise AND operation with the accumulator and the immediate value 0x0F (15 in decimal). This is effectively masking the upper 4 bits of the accumulator, retaining only the lower 4 bits.
- `jnz tp4b_a`: If the accumulator is not zero (1 to 15), it jumps to the label `tp4b_a`.
- `mov a,#16`: If the accumulator was zero, it is changed to 16.
- `tp4b_a: mov r2,a`: The accumulator's value is moved to register r2.

### Label `tp4b_b`:
This seems to be the beginning of a loop.
- `mov a,r3`: Load the "end value" into the accumulator.
- `mov b,r2`: Load the "TP-factor" into register b.
- `clr c`: Clears the carry flag.
- `subb a,@r0`: Subtracts the value pointed by register r0 from the accumulator with borrow.
- `inc r0`: Increments register r0.
- `jc tp4b_n`: If the previous subtraction resulted in a borrow (indicating the difference was negative), it jumps to the label `tp4b_n`.

The following steps involve dividing the difference by a factor, manipulating the result, and updating the TP (seems like some form of iterative division or adjustment algorithm). If the difference was positive, it continues in this block; otherwise, it goes to the `tp4b_n` label.

### Label `tp4b_n`:
This is executed if the difference was negative. It first computes the two's complement of the difference to make it positive and then follows a similar division and adjustment mechanism. The key distinction is that after the division and adjustment, the new TP is subtracted from the previous TP value.

### Looping:
- `djnz r1,tp4b_b`: Decrements register r1 and jumps to the label `tp4b_b` if r1 is not zero.

### Observations:
1. This code appears to implement an iterative algorithm to adjust or calculate some value based on a difference and a factor. The exact nature of this algorithm isn't clear without additional context.
2. The code makes use of 8051 assembly's specific instructions, such as `div ab`, `swap`, `xch`, and `subb`, to manipulate values in the accumulator and other registers.
3. There are two main paths in the loop, one for positive differences and another for negative differences.
4. The loop runs only once because r1 is initialized to 1.

### Performance:
1. The performance of this code largely depends on the input values in the accumulator, r2, and the memory location pointed by r0.
2. Since the loop runs only once, the execution time is fixed for any given set of input values.
3. The code could be optimized by minimizing register transfers and utilizing the 8051's instruction set more efficiently.
4. If this loop is intended to run multiple times, the initialization of r1 should be adjusted accordingly.

Without further context or specific input values, this is a high-level understanding of the provided 8051 assembly code. If you have additional details or specific questions, please let me know!


Сря Окт 11, 2023 6:36 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Дек 14, 2004 1:31 pm
Мнения: 3849
Мнение Re: асемблер за 8051 ядро
Освен това можеш да го помолиш да го емулира, за което собственоръчно си пише и изпълнява код на питон


Прикачени файлове:
1.png
1.png [ 646.63 KiB | Прегледано 6072 пъти ]
Сря Окт 11, 2023 6:48 pm
Профил WWW
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 13 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 1 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни