Hi! im trying to make a procedure wich saves what is on screen in a variable defined on the data segment (antes dw 2000 dup (?)). It compiles well but it freezes the program when it is called by it(program). BTW: this program is in textmode 80x25 16-bit and i am not allowed to use BIOS or DOS interruptions:

;Saves the screen image insede a rectangle
;in variable antes on the data segment.
;gets the upper left corner of the rectangle from bx
;gets the lower right corner of the rectangle from ax
;the rectangle's width in cx

        ;|------cx---------|
        ;
        ;
        ;bx-----------------
        ;|                 |
        ;|                 |
        ;------------------ax
	guarda	PROC	NEAR
			push	ax
			push	bx
			push	cx
			push	dx
			push	si
			xor		si, si
	c2:		push            cx
			push	        bx
			mov	dx, word ptr es:[bx]
			mov		antes[si], dx
			inc		si
			add		bx, 2
			loop	        c2
                        pop             cx
			cmp		ax, bx
			je		fgurda
			pop		bx
			add		bx, 160
			jmp		c2
	fgurda:         pop		bx
			pop		si
			pop		dx
			pop		cx
			pop		bx
			pop		ax
			ret
	guarda	EndP

Any ideas of what is wrong?

Edited 5 Years Ago by maxrio: n/a

what's the value of es when that function is entered? The screen address is at 0xB800:0000, so you have to read starting from there. I think your function needs to set the value of es and not assume it already contains the correct segment value.

bx = upper left corner
ax = lower right corner
cx = width -- this is one problem. We need the height, not the width. The width can be calculated from bx and ax.

Edited 5 Years Ago by Ancient Dragon: n/a

what's the value of es when that function is entered? The screen address is at 0xB800:0000, so you have to read starting from there. I think your function needs to set the value of es and not assume it already contains the correct segment value.

bx = upper left corner
ax = lower right corner
cx = width -- this is one problem. We need the height, not the width. The width can be calculated from bx and ax.

Well, this is a procedure, that means that everything is already set up(i.e es points to b800h), i display all menus and interface but i need this procedure to display a drop down submenu.I think we have a semantic problem cuz i find easier to use width instead of height. Without this procedure the drop down submenu displays well, but i lose the image that was where the submenu is now.

you need both width and height so that your program knows how many lines of text to save. They can both be calculated when you know the upper-left and lower-right coordinates. It might be easier to just save the contents of the entire screen, write sub-menu, then restore the screen to erase the sub-menu. If you don't do anything with the color attributes than all you need is a buffer that's 24*80 = 1920 bytes. double that if you need the color attributes too.

Edited 5 Years Ago by Ancient Dragon: n/a

thanks for your help, after some rest i re-checked my code and found a few problems regarding the stack. I wasn't handling well the stack so that caused an infinite loop wich obviously filled the stack. If you check my previous code you'll find that i made a loop that pushed the cx every call and that wasn't good for the pop instruction. Here's a perfectly working code:

;Saves the screen image insede a rectangle
;in variable antes on the data segment.
;gets the upper left corner of the rectangle from bx
;gets the lower right corner of the rectangle from ax
;the rectangle's width in cx         
;|------cx---------|        
;        
;        
;bx-----------------        
;|                 |        
;|                 |        
;------------------ax

guarda	PROC	NEAR
			push	         ax
			push	         bx
			push	         cx
			push	         dx
			push	         si
			xor		si, si
			dec		cx
	c2:		push	         cx
			push	         bx
	c_1:	         mov		dx, word ptr es:[bx]
			mov		antes[si], dx
			inc		si
			add		bx, 2
			loop	         c_1
			cmp		ax, bx
			je		fgurda
			pop		bx
			add		bx, 160
			pop		cx
			jmp		c2
	fgurda:           pop		bx
			pop		cx
			pop		si
			pop		dx
			pop		cx
			pop		bx
			pop		ax
			ret
	guarda	EndP

Edited 5 Years Ago by maxrio: n/a

just a small correction, double post since i cant edit, in line 26 the code should go: add si, 2 and in line 30: jl fgurda. That's all :)

This question has already been answered. Start a new discussion instead.