How do you divide?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Ben Hsu

How do you divide?

Post by Ben Hsu »

Greetings,
I've been fooling around with the pmode initialization
stuff, and I now need to be able to write to my CRT
once when pmode is entered. So I begin writing codes to
display on the screen by writing to the video memory.

A problem that I encountered was that I need to find out
the offset that the character is to be written, and to
record down the position, as a testing program, I've been
writin it out using NASM and whenever I try to do something like
this:

cursor_pos dw 0

;; --------------------------------------------------
;; int write_video(void* src_buffer, int old_coord)
;; * returns the current position of cursor
;; * (void*)src_buffer pointers to the 0-terminated string to be displayed
;; * every program uses their own page, so the monitor is clean by default,
;; and the cursor always begin at (0,0) if coordinate is not specified...
;; --------------------------------------------------
write_video: ;; assume to be in color_chrome CRT
push bp
mov bp,sp
call save_all ; save all the sys_reg's

cli ; lock interrupts
mov si,[bp+2] ; get the pointer inside [bp+2]
mov bx,[bp+4] ; get the old coordinates, in linear mode
mov di,[vidmem_color+bx] ; setup di to be where the video is to be written

;; parsing the 0-terminiated string...
;; no bell, bs, and other special character printed!!
;; whatever send is whatever show!
cld ; foward direction
.loop_begin:

or byte [ds:si], 0x00 ; check to see if it's 0x00
jz .done ; if true, then goto '.done'

or byte [ds:si], 0x0f ; if !(*buffer==0x0f) // 0x0f == <lf> formfeed
jnz .regular_chars ; goto .regular_chars

;; if it is a <lf>
mov ax,bx

push ax

shr ax,1 ; mem=mem/2 (bx=mem)
shr ax,4 ; divide by 4

mov bx,5

;; ---> troubling line, can't get division to work!!! <---
div ax,bx ; divide by 80 total...

;; ax:dx result: quotent(ax)-x, remainder(dx)-y
inc ax ; y++
shl ax,4 ; *16
mov cx,ax
add ax,cx
add ax,cx
add ax,cx
add ax,cx
add ax,cx ; *5
mov bx,ax
shl bx,1 ; *2
mov di,[vidmem_color+bx]
inc si
jmp .loop_begin ; continue

.regular_chars:
movsb ; move the byte there
inc bx ; increment bx so that <lf> will be valid position

push ax
mov al,0x07 ; write the display attribute
pop ax
lodsb
inc bx

jmp .loop_begin ; go back to beginning...

.done:
sti ; do interrupts again
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; have to do something with ax before goes off
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov [bp+28],bx ; returning value in ax

call restore_all ; restore all the sys_reg's
pop bp ; restore bp, used before save_all

ret ; go home

The compiler tells me that i've got a invalid combination of operands,
but this syntax is exact the way taught in the NASM manual.

I tried different ways to write that line with:

div ax,dx

but i don't seem to see anything different than:
"invalid combination of opcode and operands"

i'm kind of stuck here with the coding, need a little bit
of help...and is there anyway to get (x,y) position of
the cursor than passing it back and forth?

Ben
J. Morford

RE:How do you divide?

Post by J. Morford »

>On 2002-01-27 22:38:12, Ben Hsu wrote:
>Greetings,
> I've been fooling around with the pmode initialization
>stuff, and I now need to be able to write to my CRT
>once when pmode is entered. So I begin writing codes to
>display on the screen by writing to the video memory.
>
>A problem that I encountered was that I need to find out
>the offset that the character is to be written, and to
>record down the position, as a testing program, I've been
>writin it out using NASM and whenever I try to do something like
>this:
>
>cursor_pos dw 0
>
>;; --------------------------------------------------
>;; int write_video(void* src_buffer, int old_coord)
>;; * returns the current position of cursor
>;; * (void*)src_buffer pointers to the 0-terminated string to be displayed
>;; * every program uses their own page, so the monitor is clean by default,
>;; and the cursor always begin at (0,0) if coordinate is not specified...
>;; --------------------------------------------------
>write_video: ;; assume to be in color_chrome CRT
> push bp
> mov bp,sp
> call save_all ; save all the sys_reg's
>
> cli ; lock interrupts
> mov si,[bp+2] ; get the pointer inside [bp+2]
> mov bx,[bp+4] ; get the old coordinates, in linear mode
> mov di,[vidmem_color+bx] ; setup di to be where the video is to be written
>
> ;; parsing the 0-terminiated string...
> ;; no bell, bs, and other special character printed!!
> ;; whatever send is whatever show!
> cld ; foward direction
>.loop_begin:
>
> or byte [ds:si], 0x00 ; check to see if it's 0x00
> jz .done ; if true, then goto '.done'
>
> or byte [ds:si], 0x0f ; if !(*buffer==0x0f) // 0x0f == <lf> formfeed
> jnz .regular_chars ; goto .regular_chars
>
> ;; if it is a <lf>
> mov ax,bx
>
> push ax
>
> shr ax,1 ; mem=mem/2 (bx=mem)
> shr ax,4 ; divide by 4
>
> mov bx,5
>
>;; ---> troubling line, can't get division to work!!! <---
> div ax,bx ; divide by 80 total...
>
> ;; ax:dx result: quotent(ax)-x, remainder(dx)-y
> inc ax ; y++
> shl ax,4 ; *16
> mov cx,ax
> add ax,cx
> add ax,cx
> add ax,cx
> add ax,cx
> add ax,cx ; *5
> mov bx,ax
> shl bx,1 ; *2
> mov di,[vidmem_color+bx]
> inc si
> jmp .loop_begin ; continue
>
>.regular_chars:
> movsb ; move the byte there
> inc bx ; increment bx so that <lf> will be valid position
>
> push ax
> mov al,0x07 ; write the display attribute
> pop ax
> lodsb
> inc bx
>
> jmp .loop_begin ; go back to beginning...
>
>.done:
> sti ; do interrupts again
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ;; have to do something with ax before goes off
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> mov [bp+28],bx ; returning value in ax
>
> call restore_all ; restore all the sys_reg's
> pop bp ; restore bp, used before save_all
>
> ret ; go home
>
>The compiler tells me that i've got a invalid combination of operands,
>but this syntax is exact the way taught in the NASM manual.
>
>I tried different ways to write that line with:
>
>div ax,dx
>
>but i don't seem to see anything different than:
>"invalid combination of opcode and operands"
>
>i'm kind of stuck here with the coding, need a little bit
>of help...and is there anyway to get (x,y) position of
>the cursor than passing it back and forth?
>
>Ben

div only takes one operand... the value by which
you want to divide ax. All you need is:
div bx
Guest

RE:How do you divide?

Post by Guest »

>On 2002-01-28 09:11:34, J. Morford wrote:
>>On 2002-01-27 22:38:12, Ben Hsu wrote:
>>Greetings,
>> I've been fooling around with the pmode initialization
>>stuff, and I now need to be able to write to my CRT
>>once when pmode is entered. So I begin writing codes to
>>display on the screen by writing to the video memory.
>>
>>A problem that I encountered was that I need to find out
>>the offset that the character is to be written, and to
>>record down the position, as a testing program, I've been
>>writin it out using NASM and whenever I try to do something like
>>this:
>>
>>cursor_pos dw 0
>>
>>;; --------------------------------------------------
>>;; int write_video(void* src_buffer, int old_coord)
>>;; * returns the current position of cursor
>>;; * (void*)src_buffer pointers to the 0-terminated string to be displayed
>>;; * every program uses their own page, so the monitor is clean by default,
>>;; and the cursor always begin at (0,0) if coordinate is not specified...
>>;; --------------------------------------------------
>>write_video: ;; assume to be in color_chrome CRT
>> push bp
>> mov bp,sp
>> call save_all ; save all the sys_reg's
>>
>> cli ; lock interrupts
>> mov si,[bp+2] ; get the pointer inside [bp+2]
>> mov bx,[bp+4] ; get the old coordinates, in linear mode
>> mov di,[vidmem_color+bx] ; setup di to be where the video is to be written
>>
>> ;; parsing the 0-terminiated string...
>> ;; no bell, bs, and other special character printed!!
>> ;; whatever send is whatever show!
>> cld ; foward direction
>>.loop_begin:
>>
>> or byte [ds:si], 0x00 ; check to see if it's 0x00
>> jz .done ; if true, then goto '.done'
>>
>> or byte [ds:si], 0x0f ; if !(*buffer==0x0f) // 0x0f == <lf> formfeed
>> jnz .regular_chars ; goto .regular_chars
>>
>> ;; if it is a <lf>
>> mov ax,bx
>>
>> push ax
>>
>> shr ax,1 ; mem=mem/2 (bx=mem)
>> shr ax,4 ; divide by 4
>>
>> mov bx,5
>>
>>;; ---> troubling line, can't get division to work!!! <---
>> div ax,bx ; divide by 80 total...
>>
>> ;; ax:dx result: quotent(ax)-x, remainder(dx)-y
>> inc ax ; y++
>> shl ax,4 ; *16
>> mov cx,ax
>> add ax,cx
>> add ax,cx
>> add ax,cx
>> add ax,cx
>> add ax,cx ; *5
>> mov bx,ax
>> shl bx,1 ; *2
>> mov di,[vidmem_color+bx]
>> inc si
>> jmp .loop_begin ; continue
>>
>>.regular_chars:
>> movsb ; move the byte there
>> inc bx ; increment bx so that <lf> will be valid position
>>
>> push ax
>> mov al,0x07 ; write the display attribute
>> pop ax
>> lodsb
>> inc bx
>>
>> jmp .loop_begin ; go back to beginning...
>>
>>.done:
>> sti ; do interrupts again
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> ;; have to do something with ax before goes off
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> mov [bp+28],bx ; returning value in ax
>>
>> call restore_all ; restore all the sys_reg's
>> pop bp ; restore bp, used before save_all
>>
>> ret ; go home
>>
>>The compiler tells me that i've got a invalid combination of operands,
>>but this syntax is exact the way taught in the NASM manual.
>>
>>I tried different ways to write that line with:
>>
>>div ax,dx
>>
>>but i don't seem to see anything different than:
>>"invalid combination of opcode and operands"
>>
>>i'm kind of stuck here with the coding, need a little bit
>>of help...and is there anyway to get (x,y) position of
>>the cursor than passing it back and forth?
>>
>>Ben
>
>div only takes one operand... the value by which
>you want to divide ax. All you need is:
>div bx (dx in your example)
Guest

RE:How do you divide?

Post by Guest »

>On 2002-01-27 22:38:12, Ben Hsu wrote:

> mov bx,5
>
>;; ---> troubling line, can't get division to work!!! <---
> div ax,bx


mov bl,5
div bl

div BYTE: AX / BYTE -> AL (AH = remainder)
div WORD: DX:AX / WORD -> AX (DX = remainder)
div DWORD: EDX:EAX / DWORD -> EAX (EDX = remainder)

div DWORD is for 386+ CPU only

If the quotient is too big, you might get an overflow exception.
To avoid this, you can use extended precision divide.
See "Art Of Assembly"









; divide by 80 total...
>
> ;; ax:dx result: quotent(ax)-x, remainder(dx)-y
> inc ax ; y++
> shl ax,4 ; *16
> mov cx,ax
> add ax,cx
> add ax,cx
> add ax,cx
> add ax,cx
> add ax,cx ; *5
> mov bx,ax
> shl bx,1 ; *2
> mov di,[vidmem_color+bx]
> inc si
> jmp .loop_begin ; continue
>
>.regular_chars:
> movsb ; move the byte there
> inc bx ; increment bx so that <lf> will be valid position
>
> push ax
> mov al,0x07 ; write the display attribute
> pop ax
> lodsb
> inc bx
>
> jmp .loop_begin ; go back to beginning...
>
>.done:
> sti ; do interrupts again
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ;; have to do something with ax before goes off
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> mov [bp+28],bx ; returning value in ax
>
> call restore_all ; restore all the sys_reg's
> pop bp ; restore bp, used before save_all
>
> ret ; go home
>
>The compiler tells me that i've got a invalid combination of operands,
>but this syntax is exact the way taught in the NASM manual.
>
>I tried different ways to write that line with:
>
>div ax,dx
>
>but i don't seem to see anything different than:
>"invalid combination of opcode and operands"
>
>i'm kind of stuck here with the coding, need a little bit
>of help...and is there anyway to get (x,y) position of
>the cursor than passing it back and forth?
>
>Ben
Post Reply