An assign statement is usually used for combinational logic.Of course, if your technology allows it, you could model a latch or sequential logic out of a combinational feedback loop. But that is very rare.
An always block can readily be used for either. Whether it is combinational or sequential depends on how you trigger the execution of the block, as well as ordering of reads versus writes to variables within the same block and between different blocks. So a single always block could represent both kinds of logic at the same time.
SystemVerilog added three flavors of always blocks: always_comb, always_latch, and always_ff, to specify your intent and to report when what you've modeled doesn't match the intent.