When a window contains controls such as a tool bar and a status bar, the program usually needs to do some calculations on their relative locations when the user resizes the window. We can use a local RECT structure for each control, and call GetWindowRect for each one. But often we only need to know the control's size and not its previous location. This little routine gets that information and obviates the local RECT structure as well.
WindowSize: ;input is eax=window handle, returns eax=height and edx=width
sub esp,10h ;sizeof(RECT)
mov ecx,esp
invoke GetWindowRect,eax,ecx
pop edx ;left
pop ecx ;top
pop eax ;right
sub edx,eax
pop eax ;bottom
sub eax,ecx
ret
Nice small code Larry. :U
Cute indeed :U
I can't test it right now but check if this one works:
Quotemov ecx,esp
invoke GetWindowRect,eax,esp
On the earliest Intel PC's, the instruction "push sp" would put the /new/ value of sp on the stack. Later chips put the value of sp as it was /before/ the push. I've been superstitious about pushing the stack pointer ever since. :green
:U
sub edx,eax
;sub eax,edx
;mov edx,eax
QuoteOn the earliest Intel PC's, the instruction "push sp" would put the /new/ value of sp on the stack. Later chips put the value of sp as it was /before/ the push.
my understanding of this was that it happened only on a few 8088/8086/80188/80186's and was considered to be an error
i think they got it squared away for anything 80286 and beyond
by the way - you are really dating yourself to be knowing about that one - lol
i don't usually mess with esp on the stack, either
but, if i want to adjust the stack pointer without altering the flags...
pop [esp-4]
Hi,
Here is some text taken from a CPU identification program.
;-------------------------------------------------------------------------------+
; Early processor identification: +
; +
; CPU Method +
; +
; 808x/186+ Shift register by 32. Clears register on 808x and NEC V2/30. +
; This is because later CPUs mask sift/rotate value with 01Fh. +
; 808x/NEC PUSHA; NOP; +
; pusha is executed on V20/30, so we can check if SP has changed. +
; On 808x, pusha executes as a 2-byte nop, so SP is not changed. +
; 808x/80C8x REP ES: MOVSB ; CX = 0FFFFh +
; Test within a loop. If CX is non-zero at the end of a loop, +
; then it is a NMOS chip. If always zero, it is CMOS. +
; 18x/286 PUSH SP +
; On 286 and later, the original value of SP is stored. +
; On 18x and earlier, the new value is stored. +
; 8/16-bit Use self-modifying code (808x/8018x/Vx0) +
; The prefetch queue on 8-bit processors is 4 bytes long. +
; The prefetch queue on 16-bit processors is 6 bytes long. +
; For example, change a NOP to an INC. If executed as INC, we +
; we have an 8-bit processor. +
; ---------------------------------------------------------------- +
As I read this, I was a bit surprised as I considered the 80186
to be closer to the 80286 than the 8086. Anyway...
Cheers,
Steve N.
Regards,
i don't think that is entirely accurate, Steve
although he may have used it to discern 186's from 286's, i don't think it applied to all pre-286 chips
btw - 186's can be used in PC's (i think tandy did)
but they will not be very compatible, as many of the 186 internal peripherals are not addressed
to the same I/O map as the PC - IBM chose to ignore some of Intel's original reccomendations in that regard
Quote from: dedndave on November 30, 2009, 02:13:39 PM
but, if i want to adjust the stack pointer without altering the flags...
pop [esp-4]
Hmmm.... lea esp, [esp+4] does the same, but I must admit your version looks more impressive :bg
lol - i bet yours is faster Jochen :U
at least, you would think so, because there is no memory access
and, here, i thought i was slick - lol
mine may be smaller :bg
Quote from: dedndave on November 30, 2009, 11:50:47 PM
mine may be smaller :bg
Njet - 4 bytes each. Add esp, 4 is 3 bytes but trashes the flags.
Thx UtillMasm. Here's my correction.
WindowSize: ;input eax=window handle, returns eax=height, edx=width, and ecx=top
sub esp,10h ;sizeof(RECT)
mov ecx,esp
invoke GetWindowRect,eax,ecx
pop eax ;left
pop ecx ;top
pop edx ;right
sub edx,eax
pop eax ;bottom
sub eax,ecx
ret
and while we're at it
WindowClientSize: ;eax=hWnd, returns eax=client height, edx=client width, and ecx=0
sub esp,10h
mov ecx,esp
invoke GetClientRect,eax,ecx
pop eax ;zero
pop ecx ;zero
pop edx
pop eax
ret
Larry,
4 memory read are likely to be a lot faster than 4 unbalanced pops. 4 moves followed by a stack correction. Depends on if you are after speed or size.
Hi Dave,
Quote
although he may have used it to discern 186's from 286's, i don't think it applied to all pre-286 chips
(?) 8088, 8086, 80188, 80186, and the NEC's are all of them
right?
Quote
btw - 186's can be used in PC's (i think tandy did)
but they will not be very compatible, as many of the 186 internal peripherals are not addressed
to the same I/O map as the PC - IBM chose to ignore some of Intel's original reccomendations in that regard
Actually, my HP 200LX is 80186 based, and quite compatible
with a PC/XT from a user/programmer point of view. And it
fits into a pocket. If you have a specific known problem, I
can test for it (timing of instructions aside). It is a later design
than the Tandy, so they may have just shoe-horned exceptions
into the BIOS based on what was learned along the way.
Regards,
Steve N.
oh - the BIOS can be written to accomodate the differences
but, software that relies on certain devices being at certain I/O addresses may not work properly
the 186/188 are essentially the same CPU as the 86/88
they just added things like the PIC and counter/timers on-chip (a couple others - i don't remember all of them - lol)
the problem lies with IBM, really - they ignored Intel's original recommendations for I/O addressing
so - the peripherals on the PC are not where Intel told them to put them - lol
of course, IBM addresses have become the standard, now
that makes Intel look like the bad guy, in a way
not that Intel cares - as long as they sell chips, they are happy
EDIT- for all i know, Intel may have adopted to the IBM standards by now
i used to work for ADR Ultrasound (bio-med equip) - we used a 80186 to run the scanners
it is a very powerful little chip, really - or, at least, it was back then
in that case, it was great - we had no need to be IBM compatible
sorry for being off-topic, here - lol
Quote from: Larry Hammick on December 01, 2009, 08:45:11 AM
WindowClientSize: ;eax=hWnd, returns eax=client height, edx=client width, and ecx=0
sub esp,10h
mov ecx,esp
invoke GetClientRect,eax,ecx
pop eax ;zero
pop ecx ;zero
pop edx
pop eax
ret
Hutch, I would suggest going for size. GetClientRect in an innermost loop...?
Right now it's 17 bytes, without the mov ecx, esp it's 15, just under one para. Great little routine :thumbu
JJ,
here is how to wase the space, put an "align 16" in front of the label. :bg