Signal assignment type
Essentially, the difference boils down to whether the signal gets assigned on a clock edge or not.

Combinational code, like 
    A &lt;= B + 1
would have A being assigned B+1 "immediately," whereas 

    process(clk)
    begin
        if(rising_edge(clk)) then
            A &lt;= B + 1;
        end if;
    end process;


would result in A being assigned B+1 only on a rising clock edge.  With code like this, other blocks can use the value of A being guaranteed that its value will be stable and unchanging after a clock edge.

Registers, or clock gating in general I suppose, are really what make designs of any complication possible.  You create a pipeline of operations by putting a register at the border between operations.  For example, the input operands to an ALU must be stable - in a register- so that the ALU can execute properly, and the result of the ALU's execution should be in a register so that whatever block uses it does not 'see' the changing values inside the ALU as the calculations take place, but only the stable last result.