To expand on what Sceadwian said, the two directions of communication are almost completely separate. In a 16F877, the receive and transmit rates have to be the same, but there is no other connection between what you send and what you transmit.
To start with, get one direction to work.
In the 16F877 that you want to transmit, follow the instructions in the data sheet for setting up asynchronous transmission. The TX line will rise to near Vdd level. That is the idle state.
Connect the TX wire of the transmitting 16F877 to the RX wire of the receiving 16f877
In the 16F877 that you want to receive, follow the instructions in the data sheet for setting up asynchronous reception
Once you have done that, you can put data into the TXREG on the transmitting 16F877. Around 10 baud rate cycles later, so around 1ms if you are using 9600 baud, the RCIF flag will go high in the receiving 16F877 and you can read the 8 bits of data from the RXREG in the receiving 16F877
My hint for testing is that you should not transmit test characters as fast as possible. It is quite easy to write code that puts out more data as soon as the previous data has been transmitted. However, if you are sending one or two characters repeatedly like that, they can be read in various ways by the receiver. I have found it is better to send one or two characters, and then have a pause that is many times longer than one character, and repeat that. The data cannot be misunderstood by the receiver that way.
For true RS232 transmission, you should convert the TX voltage with the transmitter driver of a MAX232 or similar. You need to convert back again with the receiver of a MAX232 or similar to convert the RS232 levels for the RX of the 16F877. However, for short runs of cable, say less than 10m, you can just use the levels that come from the 16F877 with no conversion.