patternMinor
8086 ASM Bresenham's Line Algorithm
Viewed 0 times
bresenhamlineasm8086algorithm
Problem
As part of a first year university course in computer architecture some time ago we were tasked with learning 8086 ASM. The final course work required creating a small animation of shapes moving around the screen changing colours and the like.
As I would not expect anyone to review 720 lines of assembler I'm just going to provide my implementation of Bresenham's Line Algorithm.
Note that this is not the entire program but a single macro from the working program.
Also note that at the time of writing I had little to no experience with 8086 ASM (I still don't in fact), but I'm very interested in knowing how I did and how it could have been improved upon.
If anyone is interested in reviewing the rest of the project as well (it can be done in small parts) then let me know.
```
;=========================================================================================================
; BRESENHAM LINE ALGORITHM (lx1,ly1)-(lx2,ly2)
;=========================================================================================================
line macro lx1, ly1, lx2, ly2
local ldxsetup1, ldxsetup2, ldysetup1, ldysetup2
local lxisetup1, lxisetup2, lxisetupexit, lyisetup1, lyisetup2, lyisetupexit
local numsetup1, numsetup2, numsetupexit
local lloopstart, lloopif, lloopifexit, lloopend
pushall
mov ax, lx2
sub ax, lx1
cmp ax, 0
jge ldxsetup2
ldxsetup1:
mov bx, -1
mul bx
ldxsetup2:
mov ldx, ax
mov ax, ly2
sub ax, ly1
cmp ax, 0
jge ldysetup2
ldysetup1:
mov bx, -1
mul bx
ldysetup2:
mov ldy, ax
mov ax, lx1
mov lx, ax
mov ax, ly1
mov ly, ax
mov ax, lx2
cmp ax, lx1
jge lxisetup1
jmp lxisetup2
lxisetup1:
mov ax, 1
jmp lxisetupexit
lxisetup2:
mov ax, -1
lxisetupexit:
mov lxi1, ax
mov lxi2, ax
mov ax, ly2
cmp ax, ly1
jge lyisetup1
jmp lyisetup2
lyisetup1:
mov ax, 1
jmp lyisetupexit
lyisetup2:
mov ax, -1
lyisetu
As I would not expect anyone to review 720 lines of assembler I'm just going to provide my implementation of Bresenham's Line Algorithm.
Note that this is not the entire program but a single macro from the working program.
Also note that at the time of writing I had little to no experience with 8086 ASM (I still don't in fact), but I'm very interested in knowing how I did and how it could have been improved upon.
If anyone is interested in reviewing the rest of the project as well (it can be done in small parts) then let me know.
```
;=========================================================================================================
; BRESENHAM LINE ALGORITHM (lx1,ly1)-(lx2,ly2)
;=========================================================================================================
line macro lx1, ly1, lx2, ly2
local ldxsetup1, ldxsetup2, ldysetup1, ldysetup2
local lxisetup1, lxisetup2, lxisetupexit, lyisetup1, lyisetup2, lyisetupexit
local numsetup1, numsetup2, numsetupexit
local lloopstart, lloopif, lloopifexit, lloopend
pushall
mov ax, lx2
sub ax, lx1
cmp ax, 0
jge ldxsetup2
ldxsetup1:
mov bx, -1
mul bx
ldxsetup2:
mov ldx, ax
mov ax, ly2
sub ax, ly1
cmp ax, 0
jge ldysetup2
ldysetup1:
mov bx, -1
mul bx
ldysetup2:
mov ldy, ax
mov ax, lx1
mov lx, ax
mov ax, ly1
mov ly, ax
mov ax, lx2
cmp ax, lx1
jge lxisetup1
jmp lxisetup2
lxisetup1:
mov ax, 1
jmp lxisetupexit
lxisetup2:
mov ax, -1
lxisetupexit:
mov lxi1, ax
mov lxi2, ax
mov ax, ly2
cmp ax, ly1
jge lyisetup1
jmp lyisetup2
lyisetup1:
mov ax, 1
jmp lyisetupexit
lyisetup2:
mov ax, -1
lyisetu
Solution
These are just some quick thoughts, not a detailed analysis.
could be written as:
This means that you will be doing 2 jumps in a row (
Instead of having your loop count up (for x=0 to 10), sometimes having your loop count down to zero (for x=10 to 0) can produce (slightly) more efficient code (not sure it would work in this case):
- Comments. Enough said.
- If a conditional jump (like
jge) is not taken, execution just continues with the next instruction. So this seems redundant (likewise with numsetup1):
jge lxisetup1
jmp lxisetup2
lxisetup1:could be written as:
jl lxisetup2- You are repeatedly moving -1 into registers and using it in other ways. Why not make use of an additional register (say
si)? Set it to -1 at the top of this routine (remember to push/pop it if your calling convention requires it) and use it as needed:mul si,mov ax, si.
- A common shortcut for zeroing registers is
xor ax, ax. Produces slightly smaller code.
- Looking at your final loop, you have:
lloopstart:
cmp dx, lnumpix
jg lloopend
inc dx
jmp lloopstart
lloopend:This means that you will be doing 2 jumps in a row (
jmp lloopstart, jg lloopend). An alternative might be:cmp dx, lnumpix
jg lloopend
lloopstart:
inc dx
cmp dx, lnumpix
jle lloopstart
lloopend:Instead of having your loop count up (for x=0 to 10), sometimes having your loop count down to zero (for x=10 to 0) can produce (slightly) more efficient code (not sure it would work in this case):
mov dx, lnumpix
lloopstart:
dec dx
jnz lloopstartCode Snippets
jge lxisetup1
jmp lxisetup2
lxisetup1:jl lxisetup2lloopstart:
cmp dx, lnumpix
jg lloopend
inc dx
jmp lloopstart
lloopend:cmp dx, lnumpix
jg lloopend
lloopstart:
inc dx
cmp dx, lnumpix
jle lloopstart
lloopend:mov dx, lnumpix
lloopstart:
dec dx
jnz lloopstartContext
StackExchange Code Review Q#155733, answer score: 3
Revisions (0)
No revisions yet.