So I have this equation and these values:
x = (-53/a + d - 4 * a)/(1 + a * b);
а = {53, -1, -53, -1, -1};
b = {6, 11, -1, 5, -2};
d = {851, 3, -159, -73, -99}
I have to write a program that already has these values and just solves the equation 5 times, so like for the first time a is 53, b is 6, d is 851 and just do basic calculating. Then if the answer is even it should be divided by 2, and if it's odd it should be multiplied by 5.
The OBJ and EXE files get created without any problems but the calculations are very odd. I'm pretty sure I messed up the data in the registers because I can see that like in the 3rd equation what had to be the a value got the value from d and similar things probably happen to other variables as well, but I just don't see where in the code it starts to mess up. Can someone help me please?
.386
option casemap :none
include d:\masm32\include\masm32rt.inc
.data
header DB 'Lab work', 0
variant DB '(-53/a + d - 4*a)/(1 + a*b)', 13, 13, 0
results DB 'if a = %d, b = %d, d = %d: ', 13, 'Result before modification: %d', 13,
'Result after modification: %d', 13, 13, 0
zeroDivision DB "Set %d", 13 , "(-53/(%d) + (%d) - 4 * (%d))/(1 + (%d) * (%d)) = %d/%d", 13,
"Zero division!", 13, 13, 0
Avals DD 53, -1, -53, -1, -1
Bvals DD 6, 11, -1, 5, -2
Dvals DD 851, 3, -159, -73, -99
numerator DD 0
denominator DD 0
result1 DD 5 DUP(?)
result2 DD 5 DUP(?)
buff DB 256 DUP(?)
fOutput DB 512 DUP(?)
.code
start:
mov edi, 0
invoke wsprintf, addr fOutput, addr variant
.WHILE edi < 5
calculating:
mov eax, Avals[4 * edi] ;values of A in eax
cmp eax, 0
je error_0
mov ecx, -53
cdq
idiv eax ;-53/a in ecx
mov edx, 4
imul edx, eax ;4*a in edx
mov ebx, Bvals[4 * edi]
imul eax, ebx ;a*b in eax
inc eax ;1 + a*b in eax
cmp eax, 0
je error_0
mov denominator, eax
mov eax, Dvals[4 * edi]
add ecx, eax ;-53/a + d in ecx
sub ecx, edx ; -53/a + d - 4*a in ecx
mov numerator, ecx
cdq
idiv denominator ;(-53/a + d - 4*a) / (1 + a*b) in eax
mov result1[4 * edi], eax ;result1
test eax, 1 ;checking result1 whether it's odd or even
jnz odd ;if odd - multiply by 5, if even - divide by 2
mov esi, 2
cdq
idiv esi
jmp outif
odd:
imul eax, 5
outif:
mov result2[4*edi], eax
invoke wsprintf, addr buff, addr results, Avals[4*edi], Bvals[4*edi], Dvals[4*edi], result1[4*edi], result2[4*edi]
jmp cont
error_0:
invoke wsprintf, addr buff, addr zeroDivision, Avals[4*edi], Bvals[4*edi], Dvals[4*edi]
jmp cont
cont:
invoke szCatStr, addr fOutput, addr buff
inc edi
.ENDW
invoke MessageBox, 0, addr fOutput, addr header, 0
end start
calculating: mov eax, Avals[4 * edi];values of A in eax cmp eax, 0 je error_0 mov ecx, -53 cdq idiv eax;-53/a in ecx
The dword-sized division always divides the value in EDX:EAX
by the value in the single operand that the instruction specifies. Your code is doing it the other way round!
mov ecx, Avals[4 * edi]
mov eax, -53
cdq ; EDX:EAX = -53
idiv ecx ; EAX = (-53/a)
As a consequence the other calculations are also wrong.
Next code to help you on the way:
add eax, Dvals[4 * edi] ; EAX = (-53/a + d)
shl ecx, 2
sub eax, ecx ; EAX = (-53/a + d - a*4)
Tip: don't try to load the a , b , and d variables in the corresponding EAX
, EBX
, and EDX
registers. It might seem helpful, but trust me it doesn't...
mov esi, 2 cdq idiv esi
When the result turned out even, you were tasked to divide by 2. You should never use an actual division for this. Just shift the value to the right.
sar eax, 1
sar
is "ShiftArithmeticRight". It preserves the sign of the value. ( shr
would not preserve the sign!)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.