Konwersja kodu C na Assembler - struktury jako pola unii

0

Witam, mam spory problem z konwersją kodu C na Assembler

Mam taką unię:

 typedef union{
unsigned char BYTE;
struct{
unsigned char a:1;
unsigned char b:2;
unsigned char c:4;
}bits;
}un_X; 
un_X a;

Moim zadaniem jest konwersja kodu

 a.bits.c = a.bits.a * a.bits.b; 

oraz

 a.bits.a = a.bits.b^3
a.bits.c = a.bits.b^2 

na Assembler.

Bardzo proszę o wskazówki jak się za to zabrać.

3

I gdzie konkretnie widzisz problem? Jak checsz wyciągnąć jakieś bity z rejestru to zrób and z maska bitową

1

Pół-gotowiec: gcc file.c -S -o file.S

0

Mój problem to bardzo słaba znajomość Assemblera i to, że jest to jedno z zadań do rozwiązania na kartce więc musi się kompilować bez korekty środowiska.

Operacje and i xor rozumiem, gorzej z poprawnym 'wyciągnięciem' tych wartości z unii.
Wymyśliłem coś takiego, aczkolwiek nie uważam, że to jest poprawne rozwiązanie:

 
xor eax, eax
xor ebx, ebx
xor ecx, ecx

mov ax, [BYTE]
mov bx, [BYTE + 2]
mov cx, [BYTE + 4]

or eax, ecx

mov ebx, eax

Nie szukam na forum gotowego rozwiązania, bo zadanie i tak dostane inne. Proszę jedynie o ten fragment, w którym wyłuskuje się poszczególne wartości a.bits.a, a.bits.b, a.bits.c do rejestrów, żeby można było na nich dokonywać przekształceń z polecenia.

3

http://www.oocities.org/codeteacher/x86asm/asml1005.html

mov al, 123
mov ah, 00000001b
and al, ah

i teraz al trzyma ostatni bit liczby 123, jakbyś dał maskę 00000011b to miałby dwa ostatnie bity. A jakbyś dał 10000000b to miałby najwyższy bit.

1

no to załóżmy, że w al masz tę unię. Teraz jak chcesz wyciągnąć załóżmy a z unii. Patrzysz, na którym bicie to jest. Jest na 7 (licząc od 1). I robisz operację and, zapisując wynik do jakiegoś rejestru.

mov bl, al
and bl, 40h ; moze byc 01000000b jezeli to dla Ciebie czytelniejsze

No i teraz w bl masz ten bit, tylko, że jest on tam gdzie był czyli na 7 miejscu. Musisz go przesunąć w prawo tyle razy ile trza.

Teraz w bl masz a.bits.a robisz analogicznie dla a.bits.b. Zakładam, że wiesz jak działa mnożenie w asm to już sobie poradzisz.

Jak zrobisz mnożenie to potem z tym xorowaniem nie będziesz miał problemu pewnie

0

Bardzo dziękuję za odpowiedzi, teraz już zaczynam to rozumieć.

0

Tylko zobacz pod debuggerem czy nie pomyliłem kolejności bitów, bo nie jestem pewny na 100%, a nie mam jak teraz sprawdzić

0

Co do tego pierwszego zadania z mnożeniem to mam taki kod.

xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx

mov al, a   // unia w al
mov ah, 00001111b   // maska dla a.bits.c
and al, ah   // a.bits.c w al

mov bl, a   // unia w bl
mov ah, 00110000b   // maska dla a.bits.b
and bl, ah   // a.bits.b w bl
shr bl, 4   // przesuniecie bitow w prawo o 4

mov dl, a   // unia w dl
mov ah, 01000000b   // maska dla a.bits.a
and dl, ah   // a.bits.b w bl
shr dl, 6   // przesuniecie bitow w prawo o 6

cmp al, 0    // jezeli al == 0, to wynik takze jest rowny 0
je finish
mov al, dl   // jezeli al == 1, to wynik jest rowny dl

finish:
nop
 

Czy to rozwiązanie jest poprawne?

0

Ty tak serio? Mnożenie a*b to u ciebie mnożenie jednego bitu (!) przez dwa bity. Wiem że to jest ciężka matma ale wyobraź sobie że liczba 1-bitowa może przyjmować dokładnie 2 wartości: 0 albo 1. Mnożenie x przez taką liczbę może wiec dać dokładnie 2 wyniki - 0 albo x.

1 użytkowników online, w tym zalogowanych: 0, gości: 1