Newsgroups: comp.sys.apple2.programmer Path: blue.weeg.uiowa.edu!news.uiowa.edu!uunet!munnari.oz.au!labtam!news From: philip@labtam.oz.au (Philip Stephens) Subject: Re: Question about ORCA/C, ORCA/M subroutines, Message-ID: <1994Sep1.004708.18587@labtam.labtam.oz.au> Sender: news@labtam.labtam.oz.au (Net News system) Reply-To: philip@labtam.oz.au Organization: Labtam Australia Pty. Ltd. References: Date: Thu, 1 Sep 1994 00:47:08 GMT Lines: 218 Tony Morales writes: >I have a question dealing with ORCA/C, ORCA/M subroutines, and strings, >and why I cannot get these three things to get along with each other. >Let's say the following is an assembly subroutine which I will link in >with my main C source file: > >StringData START >String1 ENTRY > str 'This is String #1' >String2 ENTRY > str 'This is String #2' > >StringTable ENTRY > DC I4'String1' ;point this to the first string > END > >OK, this seems fine from assembly. Now, in my C program, I do this: > >extern char String1, String2; /* these are pointers to char, but */ > /* work as pointers to strings */ >extern void *StringTable; /* define as pointer to pointer */ You have made several mistakes in the above code! 1. You _cannot_ use the 'str' directive to create a string for C. Strings in C do not start with a length byte; they are instead terminated with a zero byte. Hence you should have written: String1 ENTRY DC c'This is String #1',h'00' String2 ENTRY DC c'This is String #2',h'00' 2. If you want StringTable to be an _array_ of pointers to strings, then you better allocate space for more than one pointer in that array!!! 3. String1 and String2 are an array of characters. Hence you must declare them in C as: extern char String1[], String2[]; What you declared in your code above were two character variables, not two character strings!!! 4. If StringTable is to be an array of pointers to strings, you must declare it as: extern char *StringTable[]; What you declared in your code above was a pointer to a void data type i.e. a pointer to something, but you don't know _what_ that something is. 5. If you haven't do so already, you must tell ORCA/M that the labels you are declaring in your assembler program are case sensitive. i.e. you must write at the top of your file: CASE ON If you don't do this, ORCA/M will convert String1 to STRING1 and so on, and because C is case sensitive, it won't find the labels you declared in your assembler source! * * * * * * * * It seems to me that you're confused about the concept of pointers and strings in C, since that's where most of your problems lie. Let me see if I can clear up the confusion for you. * * * * * * * * The C declaration: char Character; means that Character is a character. It is _not_ a pointer to a character. In assembler, the equivilant declaration would be: Character DS 1 i.e. you are reserving one byte of space to hold a character. If you assign an initial value to a character variable in C: char Character = 'A'; then the equivilant in assembler would be: Character DC c'A' * * * * * * * * The C declaration: char String[]; means that String is an _array_ of characters of unknown length. If you assign a value to this array: char String[] = "This is a sample string"; then in assembler you would write: String DC c'This is a sample string',h'00'; Now, when you write: String[1] you are asking for the first character in the array: 'T' But when you write: String you get a _pointer_ to the character array! This is often a point of confusion to people trying to learn C. * * * * * * * * The C declaration: char *String_ptr; means that String_ptr is a _pointer_ to a character. It is also often used as a pointer to an _array_ of characters (a string). But the point is that String_ptr is a 4-byte integer that holds the address of the character or string that it is pointing to. In assembler, the equivilant declaration would be: String_ptr DS 4 If you declare this in C: char *String_ptr = "This is a sample string"; Then in assembler you would do this: String DC c'This is a sample string',h'00' String_ptr DC i4'String' * * * * * * * * The C declaration: char **String_table; means that String_table is an _array_ of character/string _pointers_. It can also be written: char *String_table[]; to make it clear that it is array of pointers. If you then declare in C: char *String_table[] = {"first string", "second string"}; then in assembler you would write: String1 DC c'first string',h'00' String2 DC c'second string',h'00' String_table DC i4'String1, String2' * * * * * * * * >What I want to do, is first define a number of strings in assembly, >and then define a table of pointers to these strings, (also in assembly). Okay, you should be able to do this now based on what I've told you above, but let's show another example just to make things crystal clear. Here's an example of a number of C strings defined in assembly, with a array of pointers to each of these strings: In assembly: CASE ON StringData START String1 ENTRY DC c'This is string #1',h'00' String2 ENTRY DC c'This is string #2',h'00' StringTable ENTRY DC i4'String1, String2' END In C: extern char String1[]; extern char String2[]; extern char *StringTable[2]; Now beware that StringTable has being declared to have _exactly_ two elements in this example. If you want StringTable to be bigger, you must reserve space for it in the assembler code: StringTable ENTRY DC i4'String1, String2' DS 4*number_of_additional_elements Meaning in C you'd have: extern char *StringTable[2 + number_of_additional_elements]; -- =========== Philip Stephens, Systems Programmer, Labtam Australia ============ ====== Owned by Motor (Mo for short), the power-purrer from Down Under ======= === DS (B+S)t Y 2 X L W C+++ I T+++ A+ E H+++ S+ V+ F Q+ P++ B+ PA+ PL+++ === "Many views yield the truth. Therefore, be not alone." -- Viggies' Prime Song