Reputation: 33
I have an equation that I want to model in Assembly language. I wrote the following code which is syntactically correct but producing wrong results in register. Final result is to be stored in DX register. The equation I am modeling is:
DX = (AX2 + (AX-1) + 2 * (AX+2)) / 2
Following is the code in assembly language for Intel microprocessor:
[org 0x0100]
jmp start
number: db 02
multiplicand: db 0
multiplier: db 0
multiResult: dw 0
squareResult: dd 0
square: mov [multiplicand], AX
mov [multiplier], AX
call multi
mov AX, [multiResult]
mov [squareResult], AX
ret
multi: mov CL, 8
mov BX, [multiplicand]
mov DX, [multiplier]
carryCheck: shr BX, 1
jnc skip
add [multiResult], BX
skip: shl BX, 1
dec CL
jnz carryCheck
ret
start: mov AX, [number]
call square
mov DX, [squareResult]
sub byte[number], 1
add DX, AX
add byte[number], 2
mov AX, [number]
mov [multiplicand],AX
mov byte[multiplier], 2
call multi
add DX, [multiResult]
shr DX, 1 ; division by 2
mov AX, 0x4c00 ;ending program
int 0x21
Upvotes: 1
Views: 273
Reputation: 159
At the carryCheck:
label, the instruction shr BX, 1
should be shr DX, 1
.
Upvotes: 0
Reputation: 365147
You are making this way too complicated. First, simplify the expression to one that's easier to compute
(AX*AX + (AX-1) + 2 * (AX+2)) / 2;
(AX*AX + AX + 2*AX - 1 + 2) / 2
(AX*AX + 3*AX + 1) / 2
(AX*(AX+3) + 1) / 2
That's easy and straightforward to implement:
mov dx, ax
add dx, 3 ; dx = ax+3
mul dx ; dx:ax = ax * (ax+3)
inc ax ; ignore the high-half of the mul result in DX.
shr ax, 1
mov dx, ax ; apparently you want the result in DX?
Or are you supposed to keep 32-bit temporaries? If so, use ADD/ADC to add 1 to DX:AX. If you're using emu8086 or something, then you can't use SHRD to shift a bit from DX into AX. So you could use SHR to shift a bit out of DX, and RCR to shift that bit into AX.
You'd also need to save the carry-out from AX+3 if you do it this way.
BTW, you can easily ask a compiler for ideas. gcc doesn't really do pure 16-bit, though, and with 32-bit unsigned
compiling in 32-bit mode, it uses LEA in ways that 16-bit addressing modes don't support. But here's what I tried on Godbolt.
If you want to fix your original code, use a debugger. IDK why you're branching on anything, or using memory for anything, and there are no comments.
Upvotes: 1