Assembler - obliczanie działania

0

Witam. Zacząłem się uczyć Assemblera, muszę poprawić program liczący d/(b-c)*(a+b) z takiego:

                :MODEL  SMALL

Dane            SEGM

a               EQU     20
b               DB      10
c               =       5
d               DB      3

Dane            ENDSGM

Wynik           =       ?

Kod             SEGMENT

                ASIUM   CS:Dane, DS:Kod, SS:Stos

Start
                mov     cs, SEGMET Dane
                mov     ds, cs

                mov     ax, d
                sub     bx, WORD PTR c
                mov     bx, WORD PTR b
                div     BYTR PTR bx
                muv     a, ax
                mol     cx
                add     bl, WORD PTR b

                mov     al, Wynik

                mov     ax, 4C15h
                int     21h

Kod             ENDSGMT

Stosik          SEGM    STAC

                DB      100h DUP (*)

Stosk           ENDSGMT

                ENDP    Stort

Przeleciałem debuggerem nawet niby działa ale zawiesza się po odpaleniu :( Proszę o pomoc. Zrobiłem tyle:


                .MODEL  SMALL						
				
Dane            SEGMENT												

a               EQU     20
b               EQU     10											
c               EQU     5							
d               EQU     3							
Wynik            DB     	0								

Dane            ENDS								



Kod             SEGMENT

                ASSUME   CS:Kod, DS:Dane, SS:Stosik	

Start:												
                mov     ax, SEG Dane				
                mov     ds, ax						
	        mov 	  ax, b						
                mov     bx, d						
                sub     ax, c						
                div     BYTE PTR bx					
		mov 	cx, a						
                add     cx, b						
		mul     cx    						
                mov     Wynik , al					
		mov     ah, 09h
		mov 	dx , OFFSET Wynik
		int  	21h
				
                mov     ax, 4C00h   				
                int     21h

Kod             ENDS   								

Stosik          SEGMENT    STACK						

                DB      100h DUP (?)				

Stosik          ENDS								

                END   Start							
0

A pod debugerem też się zawiesza? Odpal to sobie pod emu8086

0

Nie, nie Shalom. Ten kod u góry jest specjalnie zmodyfikowany żeby go poprawić. Mój jest ten na dole już poprawiony.

Przeleciałem go sobie turbo debuggerem, wartości się niby w rejestrach dobrze zmieniają tylko nie wiem co z tym Wynik. Na debuggerze się nie wywala tylko przy odpaleniu w dosie

0

divide error - overflow.
to manually process this error,
change address of INT 0 in interrupt vector table.

to sie tyczy dzielenia

Tak jakbym przekroczył zakres, nie zabardzo wiem co z tym zrobić :(

Jeszcze wywala:

INT 21h, AH=09h -
address: 07100
byte 24h not found after 2000 bytes.
; correct example of INT 21h/9h:
mov dx, offset msg
mov ah, 9
int 21h
ret
msg db "Hello$"

przy int 21h :/

0

A od kiedy w ogóle można wykonywac działania na pamięci zamiast na rejestrach? W ten sposób wcale nie odejmujesz / dodajesz etc wartości pod komórką pamięci tylko operujesz adresami...

0

Przepraszam za wszelkie błędy (od 2 dni dopiero mam do czynienia z assemblerem)

Aktualnie mam taki kod z 1 błędem:

                .MODEL  SMALL						; . zamiast :
				
Dane            SEGMENT								; SEGMENT zamiast SEGM					

a               EQU     20
b               EQU     10							; EQU zamiast DB				
c               EQU     5							; EQU zamiast =
d               EQU     3							; EQU zamiast DB
Wynik           DB     	?							; przeniesienie do Segmentu

Dane            ENDS								; ENDS zamiast ENDSGM



Kod             SEGMENT

                ASSUME   CS:Kod, DS:Dane, SS:Stosik	; ASSUME zamiast ASIUM. CS:Kod zamiast CS:Dane, DS:Dane zamiast DS:Kod , SS:Stosik zamiast SS:Stos

Start:												; brakuje : po start
                mov     ax, Dane				    ; usuniecie SEGMENT , ax , zamiast cs
                mov     ds, ax						; ax zamiast cs
		mov 	ax, b						; zamiana bx na ax
                mov     bx, d						; zamiana ax na bx
		mov 	cx ,c
                sub     ax, cx						; usuniecie WORD PTR , zamiana bx na ax
                div     BYTE PTR bx					; BYTE zamiast BYTR
		mov 	cx, a						; dopisanie bx, a
	        mov	bx, b
                add    cx, bx					; usuniecie WORD PTR
		mul     cx    						; mul zamiast mol (zmiana miejscami) , zmiana ax na bx
                mov     [Wynik] , al					; zamiana al, Wynik oraz al z ax
		mov     ah, 09h
		mov 	dx , OFFSET Wynik
		int  	21h
				
                mov     ax, 4C00h   				; 4C00h zamiast 4C15h
                int     21h

Kod             ENDS   								; ENDS zamiast ENDSGMT

Stosik          SEGMENT    STACK						; SEGMENT STACK zamiast SEGM STAC

                DB      100h DUP (?)				; znak ? zamiast *

Stosik          ENDS								; Stosik zamiast Stosk i ENDS zamiast ENDSGMT

                END   Start							; END zamiast ENDP i Start zamiast Stort



  1. Jak zrobić bo ta wartość rejestru ax czy al była przypisana do Wynik i potem to wyswietlic? Program nadal pada
0
mov     ds:[Wynik] , al

Poza tym mylisz wartości liczbowe ze znakami ascii. Weź pod uwagę że jak masz liczbę gdzieś to wypisanie jej na ekran "tak po prostu" wypisze ci jej reprezentacje w ascii

0

Shalom mógł byś wspomóc jakimś przykładem? Nie koniecznie musi być na moim programie, chciał bym mieć jakieś odniesienie jak to powinno dobrze wyglądać? Tzn Wartość liczbowa, przypisanie i czy działanie na rejestrach już jest ok?

  1. czemu w tym kodzie masz
mov ds:[Wynik],al
  1. divide error - overflow.
    to manually process this error,
    change address of INT 0 in interrupt vector table.

Cały czas problem przy dzieleniu. Nie wiem co z tym począć :(

0
mov dl, 10
rozklad_cyfr:
  cmp al,10 ;czy juz cyfra?
    jb cyfra
  div dl ;w al mamy ax/dl i w ah mamy ax mod dl	
  add ah,'0'
  push ax ;zrzucamy cyfre na stos
  inc cx  ;zliczamy ile cyfr należy zdjąć			
    jne rozklad_cyfr
cyfra: ;mamy już tylko jedną cyfrę, zabezpieczenie przed okresowymi ułamkami binarnymi
  mov ah,al
  add ah,'0'
  push ax
  inc cx
jmp wypisz

i pod etykietką "wypisz" musisz pościągać ze stosu tyle "znaków" ile masz w liczniku CX i wypisać to znak po znaku, albo wpakować do jednego stringa i potem wypisać.
2. bo jak nie podasz w jakim segmencie lezy dana zmienna to defaultowo założy że w CS a tego byś nie chciał...
3. Co się dziwisz skoro dokonujesz dzielenia z jakąś wartością ADRESU zamiast z liczbą? Przecież twoje bx w tamtym miejscu nie ma wcale wartości pod komórką pamięci ds:[b] tylko ADRES tej komórki...

0
mov     bx, ds:[d]
div     BYTE PTR bx

Czy tak już jest wartością?

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