Reputation: 21
I have to create a small program which carries out the formula and gives the right answer using assembler language with EMU8086 microprocessor emulator. I coded it, there were some errors, I succeed to fix them but the answer which it gives is not correct. I spent a lot of time trying to solve this problem, but unfortunately, unsuccessfully. I need help.
Formula:
y = |x+b| if c = a*x
y = a^2 - 3*b if c < a*x
y = ] (2*c-a) / (c+a*x) [ if c > a*x
][ - means bring out only whole number not remnant.
Set variables:
a=3
b=4
c=6
array x[] = 2,3,1,4,5
array y[] is the answers
So this is the basic point. Here it counts multiplication of a*x and compares the result with variable c. Depending on result it should switch to different calculations.
cikl: ; cycle starts
XOR dx,dx
MOV bx,a ; bx=a
MOV al,x[si]
XOR ah,ah
MUL bx;
JC kl1; overflow
CMP ax,0 ; compare ax with 0
JB f2 ; if a*x < 0 jump to f2
JA f3 ; if a*x > 0 jump to f3
So it should give me this result like this:
x=2 y=6
x=3 y=-3 (overflow error should be here)
x=1 y=1
x=4 y=8
x=5 y=9
But currently it prints this: screenshot
Code:
; task: | x+b | if c= a*x
; a^2 - 3*b if c< a*x
; ] ( 2c-a ) / ( c+ax ) [ if c> a*x
; a=DW b=DB c=DB x=DB y=DW
;
stekas SEGMENT STACK
DB 256 DUP(0)
stekas ENDS
duom SEGMENT
a DW 3;
b DB 4;
c DB 6;
x DB 2,3,1,4,5
kiek = ($-x);
y DW kiek dub(0AAh)
isvb DB 'x=',6 dup (?), ' y=',6 dup (?), 0Dh, 0Ah, '$'
perp DB 'Perpildymas', 0Dh, 0Ah, '$'
daln DB 'Dalyba is nulio', 0Dh, 0Ah, '$'
netb DB 'Netelpa i baita', 0Dh, 0Ah, '$'
spausk DB 'Skaiciavimas baigtas, spausk bet kuri klavisa,', 0Dh, 0Ah, '$'
duom ENDS
prog SEGMENT
assume ss:stekas, ds:duom, cs:prog
pr:
MOV ax, duom ;move data to ax
MOV ds,ax
XOR si,si ; si=0
XOR di,di ; di = 0;
MOV cx,kiek ; cx = kiek
JCXZ pab ; if kiek = 0 jump to the end
cikl: ; cycle starts
XOR dx,dx
MOV bx,a ; bx=a
MOV al,x[si]
XOR ah,ah
MUL bx;
JC kl1; overflow
CMP ax,0 ; compare ax with 0
JB f2 ; if a*x < 0 jump to f2
JA f3 ; if a*x > 0 jump to f3
; part of task: | x+b | if c= a*x
f1:
MOV al, b
MOV dl, x[si]
ADD al, x[si]
JC kl1
JMP re
; a^2 - 3*b if c< a*x
f2:
MOV ax, a
XOR ah, ah
MOV bl, al
MUL bl
JC kl1; overflow
MOV dx, ax
XOR ax, ax
XOR bl, bl
MOV bl, 3
MOV al, b
XOR ah, ah
MUL bl
JC kl1; overflow
SUB dx, ax
XOR ax, ax
MOV ax, dx
JMP re
; ] ( 2c-a ) / ( c+ax ) [ if c> a*x
f3:
MOV al, c
XOR ah, ah
MOV dl, 2
MUL dl
JC kl1; overflow
XOR dl, dl
MOV dx, a
SUB ax, dx
CMP ax, 0
JE kl2; number can be only positive
XOR dl, dl
MOV bx, ax
XOR ax, ax
MOV dx, a ; dx=a
MOV al, x[si]
XOR ah, ah
MUL dx;
JC kl1;overflow
XOR dx, dx
MOV dl, c
ADD ax, dx
JC kl1;overflow
MOV dx, ax
MOV ax, bx
MOV bx, dx
XOR dx, dx
DIV bx
JC kl1
XOR ah, ah
re:
CMP ax, 0 ;does result fit
JE ger
JMP kl3
ger:
MOV y[di], ax
INC si
;INC si
;INC di
INC di
LOOP cikl
pab:
;bring out results to screen
;============================
XOR si, si
XOR di, di
MOV cx, kiek
JCXZ is_pab
is_cikl:
MOV al, x[si] ; number x is in ax reg.
XOR ah,ah
PUSH ax
MOV bx, offset isvb+2
PUSH bx
CALL binasc
MOV ax, y[di]
;XOR ah, ah ; number y is in ax reg.
PUSH ax
MOV bx, offset isvb+11
PUSH bx
CALL binasc
MOV dx, offset isvb
MOV ah, 9h
INT 21h
;============================
INC si
;INC si
iNC di
;INC di
LOOP is_cikl
is_pab:
;===== PAUSE ===================
;===== press any key ===
LEA dx, spausk
MOV ah, 9
INT 21h
MOV ah, 0
INT 16h
;============================
MOV ah, 4Ch ; program ends, come back to OS
INT 21h
;============================
kl1: LEA dx, perp
MOV ah, 9
INT 21h
XOR al, al
JMP ger
kl2: LEA dx, daln
MOV ah, 9
INT 21h
XOR al, al
JMP ger
kl3: LEA dx, netb
MOV ah, 9
INT 21h
XOR al, al
JMP ger
; convert number to decimal and save
; ASCII kode. Parametrai perduodami per steka
; in ASCII code. Parameters pass through stack
; Fist parameter ([bp+6])- converted number
; Second parameter ([bp+4])- place for result
binasc PROC NEAR
PUSH bp
MOV bp, sp
; saving used registers
PUSHA
; Filling line with spaces
MOV cx, 6
MOV bx, [bp+4]
tarp: MOV byte ptr[bx], ' '
INC bx
LOOP tarp
; number is prepared for DIV is 10
MOV ax, [bp+6]
MOV si, 10
val: XOR dx, dx
DIV si
; remnant to ASCII code
ADD dx, '0' ; can be--> ADD dx, 30h
; write number to the end of the line
DEC bx
MOV [bx], dl
; count number of converted symbols
INC cx
; do we need to DIV more ?
CMP ax, 0
JNZ val
POPA
POP bp
RET
binasc ENDP
prog ENDS
END pr
Upvotes: 1
Views: 247
Reputation: 9899
CMP ax,0 ; compare ax with 0 JB f2 ; if a*x < 0 jump to f2 JA f3 ; if a*x > 0 jump to f3
You want to have 3 different outcomes depending on Sign(a*x)
.
In order to achieve that you need to treat the product in a*x as a signed number. In assembly programming you do this by using the signed versions of the conditional jumps (jl
, jg
, ...). You've used the unsigned versions instead (jb
, ja
, ...).
CMP ax,0 ; compare ax with 0
JL f2 ; if a*x < 0 jump to f2
JG f3 ; if a*x > 0 jump to f3
XOR dx, dx DIV bx JC kl1 XOR ah, ah re:
This JC kl1
will jump based on the current value of the carry flag (CF), but since the DIV
instruction leaves all flags undefined, there's no telling what the CF will be at this point in the program. It could be that it is still clear from the preceding xor dx, dx
, but that need not always be the case. If INTEL would have documented the DIV
instruction to leave the flags unmodified, it would have been the case though.
Bottomline is that your program will behave erratically.
Upvotes: 3