![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Newbie
Join Date: Dec 2004
Posts: 7
Rep Power: 0
![]() |
I'm not new to x86 ASM, but I am new to the square-root-related instructions that Intel has provided. I don't know what I'm doing wrong in my program, but I get a divide overflow. Perhaps someone could take a look at my code and see what is causing this.
This program isn't finished yet, but it's going to draw a sphere. I am doing it purely out of experimental interest. Right now I am just trying to get it to draw pixels to the screen, but I won't know if my algorithms and such are right or not if I can't see anything but an error. I wonder if it's the way I've used the square-root. This is the first time I've made use of it in ASM, so I don't even know if I did it right or not. Anyway, any help would be appreciated. BTW: If you find the below code to be hard to read due to the lack of 'tabs' on these forums, you can download the source file -- http://shadowsoft-games.com/saxman/3D.ASM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This program is designed to draw a sphere using the following: ; ; Ymax = (Ry/Rx) SQRT(Rx^2 - X^2) ; Zmax = (Rz/Ry) SQRT(Ry^2 - Y^2) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; jmp start xpos* dw ?*; X position (0-319) ypos* db ?*; Y position (0-199) zpos* db ?*; Z position (0-255) xrad* db 64*; X radius (0-255) yrad* db 64*; Y radius (0-255) zrad* db 64*; Z radius (0-255) store1 dd ?*; Used to store a floating-point ymax* db ?*; Ymax = (Ry/Rx) SQRT(Rx^2 - X^2) zmax* db ?*; Zmax = (Rz/Ry) SQRT(Ry^2 - Y^2) palette db 00, 00, 00, 01, 01, 01, 02, 02, 02, 03, 03, 03 * db 04, 04, 04, 05, 05, 05, 06, 06, 06, 07, 07, 07 * db 08, 08, 08, 09, 09, 09, 10, 10, 10, 11, 11, 11 * db 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15 * db 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19 * db 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23 * db 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27 * db 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31 * db 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35 * db 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39 * db 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43 * db 44, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47 * db 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51 * db 52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55 * db 56, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59 * db 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63 start: mov ax, 13h* *; Setup 320x200 video mode int 10h mov ax, 0a000h* *; Set the video address mov es, ax write_palette: mov si, offset palette mov cl, 192* *; Read 192 color values (64 total colors) mov dx, 03c8h* *; Set the palette address xor** al, al out dx, al cld inc dx rep outsb draw_setup: mov di, 16000* *; Start from the center of the screen mov dx, 63* *; DX is our color selection call calculate_ymax draw_y: ;mov dx, 63 mov es:[di], dx inc ypos sub di, 320 mov al, ymax cmp ypos, al jl draw_y inc xpos mov di, 16000 add di, xpos call calculate_ymax mov ax, word xrad cmp xpos, ax jl draw_y calculate_ymax: ; Ymax = (Ry/Rx) SQRT(Rx^2 - X^2); push ax push dx mov ax, word yrad div xrad mov bx, ax* *; BX acts as (Ry/Rx) mov ax, word xrad mul xrad push ax mov ax, xpos mul xrad pop dx sub ax, dx mov word store1, ax ; (Ry/Rx) fld store1* *; Load X fld st(0)* **; Duplicate X on TOS fsqrt* * *; Computer SQRT(X**2 + Y**2) fst store1* *; Store away result in Z mov ax, word store1 mul bx mov ymax, al pop dx pop ax ret ; |
|
|
|
|
|
#2 |
|
Expert Programmer
|
When you divide with asm this is what happens.
You take usually a 32bit value (though it can be 16bit, or 8bit) perform the division and store both the result and the remainder (no decimal values here) into the same block of data we performed the operation on. Which means dividing a 32bit value results in that 32bit value being broken into a 16bit result and a 16bit remainder. I am sure you can see where this goes wrong now... What happens if you take a 32bit value, which requires all 32 bits and divide that value by 1? Well as you can imagine the result WILL NOT fit in the 16 bit register in which it is supposed to fit. One of your flags should be raised for this exception, probably OF, you will need to verify that and start checking that flag to make sure that the division occured without error and deal with the error when it occures appropriatly.
__________________
Clifford Matthew Roche <geek@cliffordroche.com> Web Hosting: http://www.crd-hosting.com Consulting: http://www.crdev-consulting.com |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|