In reply to Broxigar:
This is a simulation race condition. SystemVerilog guarantees executing the statements within a begin/end block in source order. But there are no guarentees of ordering between processes execting in the same event region. The continuous assign is a separate process. There is no ordering guarantees when the right hand side gets a evaluated with respect to the other process. It could happen immediately when there is a change, or happen after the begin/end block finishes.
You should be using nonblocking assignments to any variable written in a sequential block that is read outside the block. Then $display is guaranteed to print the old value of sum. In any case, you could use $strobe instead which prints the new value of sum.
BTW, in the code shown, there is no need for $signed as the operands are already signed. Also use 32’sd for signed decimal literals.