www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/04/13/10:05:38

From: "A. Sinan Unur" <asu1 AT cornell DOT edu>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Problem with Packed structs
Date: Sun, 13 Apr 1997 08:23:54 -0400
Organization: Cornell University http://www.cornell.edu
Lines: 81
Sender: asu1 AT cornell DOT edu (Verified)
Message-ID: <3350D05A.3B4D@cornell.edu>
References: <AEA78966EE AT fs2 DOT mt DOT umist DOT ac DOT uk> <9704121940 DOT AA20198 AT eed DOT miee DOT ru>
Reply-To: asu1 AT cornell DOT edu
NNTP-Posting-Host: cu-dialup-0052.cit.cornell.edu
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Oleg Yu. Polyanski wrote:
>>> (1) When calling an interrupt, I often need to declare a packed 
>> struct which matches the layout of the data needed or provided by the 
>> interrupt.

this is mostly out of curiousity, i am not trying to take sides in the
packed vs not packed. however, i read that the order of the fields in a
packed struct need not remain the same from one version of the compiler
to the other. this means using packed structs may not be safe for
interrupt related routines. playing around with my neverending netbios
project (where i had copies of network control blocks in my memory space
which were copied to the approriate location in dos memory before
invoking the interrupt), i thought one 'solution' to this would be to
define a number of offsets instead of the structure itself. for example,
instead of using

/* Network Control Block (NCB) */
 
typedef struct {
BYTE	cmd;		/* command code */
BYTE	ret_code;	/* return code */
BYTE	lsn;		/* local session number */
BYTE	ncb_num;	/* "ncb_num"  ADD NAME */
WORD	io_off;		/* offset of the IO buffer */
WORD	io_seg;		/* segment of the IO buffer */
WORD	len;		/* length of data in the buffer */
BYTE	rmt_name[16];	/* name of remote system to call */
BYTE	lcl_name[16]; 	/* name of the local machine */
BYTE	rec_to;		/* receive timeout in 1/2 seconds */
BYTE	snd_to;		/* send timeout in 1/2 seconds */
WORD	post_off;	/* offset of the POST routine */
WORD	post_seg;	/* segment of the POST routine */
BYTE	lana;		/* lan adapter no: 0x00 - 0x03 */
BYTE	cmp_code;	/* completion code */
BYTE	rsrv[14];	/* reserved area of 14 BYTEs */
}__attribute__((packed)) NCB;

and then copying it to the allocated dos memory (using movedata or
dosmemput), one could define:

/* Offsets of NCB fields */

#define O_CMD		0x00
#define O_RET_CODE	0x01
#define O_LSN		0x02
#define O_NCB_NUM	0x03
#define O_IO_OFF	0x04
#define O_IO_SEG	0x06
#define O_LEN		0x08
#define O_RMT_NAME	0x0A
#define O_LCL_NAME	0x1A
#define O_REC_TO	0x2A
#define O_SND_TO	0x2B
#define O_POST_OFF	0x2C
#define O_POST_SEG	0x2E
#define O_LANA		0x30
#define O_CMP_CODE	0x31
#define O_RSRV		0x32


using the former, i would setup each field and then copy the struct to
conventional memory. using the latter, i would just do (for example)

	_farpokeb(_dos_ds, linear_addr_of_ncb+O_REC_TO, 10); 

does anyone care to comment on this? basically, i am beginning to feel
like it actually makes sense because (i) it completely obviates
depending on the packing order and (ii) reduces bookkeeping associated
with copies floating around. and i might even be inclined to write my
first C++ stuff to make this look beautiful. (inline member functions vs
macros.)

   -- Sinan
 
*******************************************************************
 A. Sinan Unur                                WWWWWW
                                              |--O+O
 mailto:sinan DOT unur AT cornell DOT edu                C   ^ 
 http://www.people.cornell.edu/pages/asu1/     \  ~/ 
*******************************************************************

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019