[Asembler] Operacje na bitach

0

Chciałbym aby ktoś mi pomógł napisać program. Wszystkie rady, wskazówki, triki inne pomoce mile widziane. Ów program ma na wstępie prosić o liczbę z zakresu od 0 do 255 (Liczba nie może być większa, ani nie mniejsza. Ani nie może to być litera lub inny znak). <<<Czyli już tu trzeba zrobić jakieś zabezpieczenia.
Po wpisaniu np. 10 ma on wyświetlić, że wartość hex to A, wartość oct 12, a bin 1010. I tak ma zrobić z każdą cyfrą jaką wpiszę z przedziału od 0 do 255. Ale do tej zmiany między systemami chcę wykorzystać operatora przesunięcia, a nie dzielenia!

0

50zl, a temat powinien byc w dziale praca

0

Na tym forum zasada jest taka: albo pokaz, co sam zrobiles, albo plac.

0

@Goenitz ale w czym jest problem? Bo że chcesz napisać ten program, to fajnie. Czego w takim razie nie umiesz? Wczytać znaku z konsoli?

mov ah, 01h
int 21h

Sprawdzić czy znak jest cyfrą?

cmp al, '9'
jb mniejszeod9
jmp blad
//
mniejszeod9:
cmp al, '0'
jb blad
jmp cyfra

Nie umiesz przeliczyć wczytanych znaków na liczbę? Wystarczy mnożyć sobie przez 10 i dodawać.
Nie umiesz przeliczyć liczby dziesiętnej na inny system? Google...

0

Chce to zrobić z operatorem przesunięcia, a nie dzielenia. Na chwilę obecną chciałem zamienić liczbę z przedziału od 0 do 255 na bin. Jak już poznam jak to zrobić, to wezmę się za hex i oct.

mov bl, Liczba_Dec   ; tu zostanie wpisana liczba z przedziału od 0 do 255. 
Wyswietl_Bin:
shr bl, 1
mov dl, cf   ;podobno we fladze cf zapisuje się jeden bit z przesunięcia i chce go wypisać, dlatego do dl 
mov ah, 02h
int 21h
test bl, FFh
jnz Wyswietl_Bin

Czytałem, że opcja Test działa podobno jak And, tylko nie zapisuje wyniku i poza flagami nic nie zmienia. Dlatego zastosowałem ją do sprawdzenia czy wartość w bl (co ma 8 bitów) to zero. Ale nie wiem, bo coś nie działa, bo podstawiałem za Liczba_Dec różne wartości. Ale coś tak czuje, że i tak jak by zadziałało to by nie wypisało od końca tych zero jedynek jak ja to widzę na tym przykładzie:
Weźmy np. liczbę 25dec:
25 shr o 1 = 12 reszty 1
12 shr o 1 = 6 reszty 0
6 shr o 1 = 3 reszty 0
3 shr o 1 = 1 reszty 1
1 shr o 1 = 0 reszty 1*

25dec = *11001bin
Reszta to ten ucięty bit co po przesunięciu idzie do flagi.

0

ALgorytm specjalnie pod asembler na zamiane na binarny:

  1. Liczba >> 1
  2. zmienna++
  3. wynik na stos
  4. czy liczba==0 ?
  • nie -> goto 1
  1. zmienna--
  2. ze stosu do X
  3. wypisz X
  4. czy zmienna == 0 ?
    • nie -> goto 4

Tak mniej więcej powinno Ci pomóc

0

Dzięki abc za algorytm. Tylko, że coś nie działa. Pewnie to ja coś źle robię. Proszę więc o pomoc. Oto kod:

.model tiny
.386
.data
.stack 100h
.code
mov ax, @data
mov ds, ax

mov bl, zmienna_dec ; za tą zmienną podstawiałem różne wartosci, czy to 10 czy coś innego i tak nie działa.   
Bin:
shr bl, 1
push cf   
inc cl     ; nie użyłem zmiennej a połówki rejestru do zwiększania i potem na jej podstawie obrotów do wypisywania. 
cmp bl,0
jnz Bin

Wyswietl_Bin:
pop dl
mov ah, 02h
int 21h
dec cl
cmp cl,0  ;nie działa też  test cl, FFh
jnz Wyswietl_Bin

mov ah, 4Ch
int 21h
end
0
  1. Zmień model pamięci na .small i podczas linkowania usuń parametr /t albo będziesz musiał trochę pozmieniać kod (deklarujesz model pamięci charakterystyczny dla pliku com a piszesz jak dla execa)

  2. Pierwszy raz widzę CF w kodzie asm :D
    Powinno być coś takiego(jeżeli koniecznie chcesz na CF to robić):

and dl,0
shr bl,1
jnc pisz ;skok jeżeli CF=0
pisz1:
inc dl
pisz:
add dl,30h ;Kod ASCII na cyfry to 30h-39h czyli jak masz w rejestrze 1 musisz do niego dodać 30h żeby w konsoli wyświetliło ci 1

Myślę że chyba lepiej by było jak byś trzymał liczbę w górnej części rejestru czyli

mov bh,liczba
shr bx,1/3/4(binarnie/ósemkowo/szesnastkowo)
shr bl,8-1/3/4
mov [esi],bl ; W bl będziesz mieć to co przedtem w CF
and bl,0       ;zerujemy bl dla kolejnego przebiegu
  1. Kody ASCII na cyfry to 30h-39h a litery A-F to 41h-46h (czyli jak w rejestrze masz 0-9 to dodajesz 30h a jak 10-15(A-F) to 37h żeby wyświetlić poprawny znak w konsoli).

  2. Robisz tak:
    Pobierasz 3kody znaków XYZ,
    Badasz czy 2F<X/Y/Z<3A (żeby nie zmieniać nic w kodzie szaloma - zjadł equale w jumpach i drugi powinien być ja)
    obierasz je z niepotrzebnych 3jek
    zapisujesz jako np ax = 100x+10y+z
    Badasz czy ah = 0 (przedział 0-255)
    Puszczasz przez ten swój algorytm
    Robisz z cyfr znaki i wyswietlasz

Masz wszystko co powinieneś wiedzieć

0

Mam problem z wczytaniem liczby. Mógłby powiedzieć ktoś co jest z tym nie tak? Oto kod:

.Model tiny
.Stack 100h

.Data
bufor db 4
dlugosc db 0
cyfra db 0,0,0
podaj db "Podaj liczbe od 0 do 255","$"
error db "Zla wartosc. Podaj jeszcze raz liczbe","$"

.Code
Start:

mov dx, offset podaj
mov ah, 09h
int 21h

Pobieranie:
mov dx, offset bufor
mov ah, 0ah
int 21h

;======Sprawdzanie Liczby==========

cmp dlugosc,0
jz Pobieranie

Jeden znak:
cmp dlugosc,1
jne dwa
mov al, cyfra
mov cyfra+2,al
mov cyfra,'0'
mov cyfra+1,'0'
jmp Sprawdz_cyfre

dwa:
cmp dlugosc,2
mov al, cyfra+1
mov cyfra+2, al
mov al, cyfra
mov cyfra+2, al
mov cyfra,"0"
jmp Sprawdz_cyfre:

;===========Zla Liczba===========
blad:
mov dx, offset error
mov ah, 09h ;wyswietlenie informacji o blednej liczbie
int 21h
jmp Pobieranie


;===Sprawdzanie czy to sa liczby od 0 do 9=====

Sprawdz_cyfre:
cmp cyfra,'0'
jb blad

cmp cyfra,'9'
ja blad

cmp cyfra+1,'0'
jb blad

cmp cyfra+1, '9'
ja blad

cmp cyfra+2, '0'
jb blad:

cmp cyfra+2, '9'
ja blad:

;========Konwersja Cyfry=============
konwersja_cyfry:
mov ax, cyfra
mov bx,10
mul bx
add ax, cyfra+1
mul ax, bl
add ax, cyfra+2

mov ah, 4Ch
int 21h
end 

Błędy kompilatora:
Assembling file: wczytaj.asm
Error wczytaj.asm(28) Illegal instruction
Error wczytaj.asm(44) Need expression
Error wczytaj.asm(70) Need expression
Error wczytaj.asm(73) Need expression
Error wczytaj.asm(77) Operand types do not match
Error wczytaj.asm(80) Operand types do not match
Error wczytaj.asm(81) Extra characters on line
Error wczytaj.asm(82) Operand types do not match
Error messages: 8

0

google translate sie klania... Masz napisane w których linijkach jest błąd...
masz śmieci na na końcu lini (dwukropki), etykiety nie mogą mieć spacji, mul jest jednoargumentowe, jak rejestr i operend mają różne rozmiary to w twoim przypadku używasz byte ptr.

Widze że tak średnio poprawiłeś kod - w ogóle to ci się uruchomiło i zakończyło prawidłowo chociaż raz?

0
Fallen napisał(a)

google translate sie klania... Masz napisane w których linijkach jest błąd...

Tak wiem, ale od niedawna się zajmuję tym językiem wiec nie znam jeszcze wszystkich zasad czego nie wolno a co można. I co mam robić by pozbyć się tych błędów. Dlatego prosił bym o więcej rad. Bo sam nawet jeśli zrozumiem jakie są to błędy to jeszcze bez pomocy nie uda mi się tego poprawić. To mój pierwszy większy program i dlatego jeszcze trochę się gubię. Wcześniej wczytywałem tylko sam teks zakończony $ i jakieś tam drobne rzeczy próbowałem.

Fallen napisał(a)

etykiety nie mogą mieć spacji, mul jest jednoargumentowe

Masz rację. To moje niedopatrzenie. Już to poprawiłem. Liczba błędów spadła do 3. Same "Operand types do not match".

Fallen napisał(a)

jak rejestr i operend mają różne rozmiary to w twoim przypadku używasz byte ptr.

Mógłbym prosić o rozwinięcie i poparcie tych słów przykładem bo za bardzo nie rozumiem.

Fallen napisał(a)

Widze że tak średnio poprawiłeś kod - w ogóle to ci się uruchomiło i zakończyło prawidłowo chociaż raz?

Ten co zamieściłem ani razu się nie uruchomił.

0
Goenitz napisał(a)
Fallen napisał(a)

Liczba błędów spadła do 3. Same "Operand types do not match".

Fallen napisał(a)

jak rejestr i operend mają różne rozmiary to w twoim przypadku używasz byte ptr.

Mógłbym prosić o rozwinięcie i poparcie tych słów przykładem bo za bardzo nie rozumiem.

MOV  AX, cyfra

AX jest rejestrem 16bitowym, a cyfra jest typu DB (8bitów). Zamiast tego możesz użyć

MOVZX AX, cyfra

Ten sam błąd (różne wielkości operandów) masz w obu instrukcjach ADD niżej.

0

Dzięki za pomoc. Program się już kompiluje, ale totalne bzdury się dodatkowo pojawiają.

  1. Przed napisem "Podaj liczbe od 0 do 255" wyświetla się dużo różnego rodzaju znaczków.
  2. Pogram wczytuje ciąg co ma więcej niż 3 znaki. Można ich wpisać znacznie więcej.

Kod programu wygląda tak:

.Model tiny
.Stack 100h

.Data
bufor db 4
dlugosc db 0
cyfra db 0,0,0
podaj db "Podaj liczbe od 0 do 255",13,10,"$"
error db "Zla wartosc. Podaj jeszcze raz liczbe",13,10,"$"

.Code
Start:

mov dx, offset podaj
mov ah, 09h
int 21h

Pobieranie:
mov dx, offset bufor
mov ah, 0ah
int 21h

;======Sprawdzanie Liczby==========

cmp dlugosc,0
jz Pobieranie

Jeden_znak:
cmp dlugosc,1
jne dwa
mov al, cyfra
mov cyfra+2,al
mov cyfra,'0'
mov cyfra+1,'0'
jmp Sprawdz_cyfre

dwa:
cmp dlugosc,2
mov al, cyfra+1
mov cyfra+2, al
mov al, cyfra
mov cyfra+2, al
mov cyfra,"0"
jmp Sprawdz_cyfre

;===========Zla Liczba===========
blad:
mov dx, offset error
mov ah, 09h ;wyswietlenie informacji o blednej liczbie
int 21h
jmp Pobieranie


;===Sprawdzanie czy to sa liczby od 0 do 9=====

Sprawdz_cyfre:
cmp cyfra,'0'
jb blad

cmp cyfra,'9'
ja blad

cmp cyfra+1,'0'
jb blad

cmp cyfra+1, '9'
ja blad

cmp cyfra+2, '0'
jb blad

cmp cyfra+2, '9'
ja blad

;========Konwersja Cyfry=============
konwersja_cyfry:
mov al, cyfra
mov bl,10
mul bl
add al, cyfra+1
mul bl
add al, cyfra+2

mov ah, 4Ch
int 21h
end 

Proszę o wasze kolejne fachowe rady.

0

Najlepiej byłoby gdybyś zupełnie inaczej rozwiązał pobieranie wartości z klawiatury, np z użyciem int 16h, funkcja 00h. Dodaj 2 zmienne w sekcji .DATA i .CONST

.CONST
VK_ENTER   EQU   1C0Dh   ;; kod klawisza ENTER
.DATA
dwValue DD ?
dwMax   DD ?

później wystarczy pętelka

_LOOP_READ:
  MOV   AH, 00h
  INT   16h
  CMP  AX, VK_ENTER
  JE    _LOOP_OUT:
   ;; tutaj sprawdzasz sobie dokladniej jaki znak i dokonujesz konwersji
   ;; stara liczba * 10 + nowa cyfra podana przez użyszkodnika
   ;; dobrze też dodać obsługę klawisza BACKSPACE
   ;; po zmodyfikowaniu liczby sprawdzasz czy nie przekroczyła wartości dwMax
   ;; jesli przekroczyla to ustawiasz dwValue na dwMax
  JMP   _LOOP_READ
  
_LOOP_OUT:
  ;; tutaj dalsze działania czyli w Twoim wypadku wypisanie liczby w różnych systemach

I to tyle.
O przerwaniu 16h możesz przeczytać tutaj.

0
  1. Przed napisem "Podaj liczbe od 0 do 255" wyświetla się dużo różnego rodzaju znaczków.

Jak robisz plik com to dajesz ORG 100, jak exe to tak jak miałeś @data do data segmęt. Przepraszam że namieszałem ale wydawało mi się że model tini narzuca tworzenie com`ów :)

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