Page 1 of 1

How do you divide?

Posted: Sun Jan 27, 2002 12:00 am
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

RE:How do you divide?

Posted: Mon Jan 28, 2002 12:00 am
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

RE:How do you divide?

Posted: Mon Jan 28, 2002 12:00 am
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)

RE:How do you divide?

Posted: Mon Jan 28, 2002 12:00 am
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