For starters, go here for scripting information, all functions and events are listed along with example scripts as well as a library of useful scripts.
http://wiki.secondlife.com/wiki/LSL_PortalFirst of, object communication.
You need to use the listen event to hear chat from another object (or avatar for that matter).
default
{
state_entry()
{
llListen (0, "",NULL_KEY,"");
}
listen (integer channel, string name, key id, string message)
{
llSay (0,"channel =" + (string)channel);
llSay (0,"speaker =" + (string)name);
llSay (0,"UUID Key=" + (string)id);
llSay (0,"message =" + (string)message);
}
}
The first part, in the state_entry(), is the llListen() function, this 'sets up' the listen. There's 4 pieces of information inside the parentheses. The first is the channel you wish to listen on, the second, 3rd, and 4th are filters, which are useful when you're only listening to a specific avatar or object. The second item is the name of the object to filter for, the 3rd is the key of the object to filter for, and the fourth is the message to listen for. In my example there, that's a completely open filter, so it listens for all chat from all objects and avatars, and for any message spoken. If you're communicating between objects, it's best to use negative channel numbers (only objects can speak on negative channels), and best to filter the name as well, for example, if your Object A is listening for chat commands from Object B, you might want to setup the listen for Object A as such:
llListen (-1234, "Object B", NULL_KEY, ""

;
That will listen for any chat spoken for Object B. If you're listening for just one message, "Go" for example, you may want to filter even further
llListen (-1234, "Object B", NULL_KEY, "Go"

;
The more you can filter your listens, the less likely the are to be laggy. Also, you can remove listens when they are not in use, to do that, you use a handle. Globally define a handle before the default state like so
integer handle;
then, when you setup your listen, it is done like so:
handle = llListen (-1234, "Object B", NULL_KEY, ""

;
then, if your script is not listening, you can remove the listen with llListenRemove();
llListenRemove (handle);
Receiver objects have to be within chat range to 'hear' other speaking objects, llWhisper() has a 3 meter range, llSay() has 20, and llRegionSay() can be used (only on non zero channels), to echo chat across an entire sim.
You can create links using llCreateLink (key target, integer parent); where target is the UUID key of the target prim, and parent is a Boolean that determines who the parent is and who the child is, so if parent is set to FALSE, then the target becomes the root, else the calling script's object becomes the parent. Read the wiki on linking objects to learn about root (parent) and child prims.
Now, since you're talking about linking the objects, you don't need to use listens to communicate between linked objects. You can use the link_message event and llMessageLinked(). It works similar to a listen event, but there's no channel specified, you specify scripts in the same prim (LINK_THIS), or in another prim or prims (LINK_ALL_CHILDREN), etc. Read the wiki section on llMessageLinked() and the link_message() event to see how communication is done with link messages. Whenever possible, use link messages over listens as they are faster, and far less laggy.