Let all modules be R-modules for some principal ideal domain R and let tensor products be over R.
Given a product operation like tensor (or *, see below), we can form the product of two chain complexes A and B, say A tensor B, by taking all products A_i tensor B_j and letting (A tensor B)_k = directsum A_i tensor B_j where the sum is over the i,j with i+j=k. We also need a differential, and define d(a tensor b) = da tensor b + (-1)^i a tensor db when a lies in A_i. (Indeed, dd = 0.)
There is a natural map H(A) tensor H(B) -> H(A tensor B) sending a tensor b to a tensor b. (Indeed, if a is a boundary, say a = dc, and b is a cycle, then a tensor b = d(c tensor b) is a boundary, so this map is well-defined.)
For a topological space X, let us write S(X) for the singular chain complex of X.
Theorem Let X and Y be topological spaces. Then S(X × Y) is chain equivalent to S(X) tensor S(Y).
Let C,D be chain complexes, where C*D is acyclic. Then there is a short split exact sequence 0 -> H(C) tensor H(D) -> H(C tensor D) -> (H(C) * H(D)) -> 0 with maps of degree 0, 0, -1, respectively. This expresses H(C tensor D) in terms of H(C) and H(D).
Instead of doing homology with integral coefficients, we can use coefficients from an Abelian group G. The resulting chain complexes is C tensor G. The (co)homology obtained in this way is denoted H(C;G).
Let C be a free chain complex (i.e., each C_i is free). Then there is a short split exact sequence 0 -> H(C) tensor G -> H(C tensor G) -> H(C) * G -> 0 with maps of degree 0, 0, -1, respectively. This expresses H(C;G) = H(C tensor G) in terms of H(C).
There is a homomorphism H(A;G) tensor H(B;H) -> H(A tensor B; G tensor H) defined in the obvious way (using the identification (A tensor G) tensor (B tensor H) = (A tensor B) tensor (G tensor H)). This gives rise to a multiplication on homology called the cross product.
Similarly, one has a cross product on cohomology. In particular, following Eilenberg-Zilber, there is for a topological space X a map H*(X;G) tensor H*(X;H) -> H*(X;G tensor H). But the diagonal map x -> (x,x) from X into X × X gives rise to a homomorphism H*(X × X; K) -> H*(X; K), and composing that with the cross product we get the cup product H*(X;G) tensor H*(X;H) -> H*(X; G tensor H), and, in particular, H*(X) tensor H*(X) -> H*(X).
The particular incarnation of the cup product that we described above is obtained by taking the map t : S(X) -> S(X) tensor S(X) defined by t(u) = sum head(u,i) tensor tail(u,j) where the sum is over the i,j with i+j=k and head(u_0...u_k, i) = u_0...u_i and tail(u_0...u_k, j) = u_(k-j)...u_k.