First you write the program out in assembly language instructions then you convert individual instructions and keep track of the program counter on the left hand side, you will have to leave space for the operands of forward jumps because you don't know what that address will be be. Then you go back and fill them in. Easy-peasy.
There is a nice image of such a notebook here
https://www.quora.com/What-is-the-real-purpose-of-graph-pape...
which looks exactly like the listing output of an assembler because it is.
In any case, none of this was particularly difficult or unusual, just a bit tedious. At least, the part where you enter hex codes is.
Even more fun was before microcomputers. On a few minicomputers and mainframes, you would occasionally have to enter short programs in binary using switches on the front panel.
But the hand assembly part was close to the end of the process. Initially, I'd just write assembly on normal paper and not worry about converting anything to op codes until I considered the program complete enough to assemble and try running it. During that initial phase, I wouldn't worry about leaving space or anything because it was all going to be rewritten multiple times anyway.
I, like most programmers, never achieved that level of brilliance.
What they did was work out the code in their minds before entering anything into the computer.
After 6 years of being a field engineer and writing exclusively in machine language, I made the switch to being a systems analyst which gave me access to an assembler. That seemed easy after having to calculate relative jumps/subroutine calls for so long.
I would use a hand punch to create holes in paper tape that was the program. (Just a metal block with holes drilled and a metal dowel to punch the tape).
"Patching the tape" involved finding a section of code that could be "overpunched" to be a jump instruction to the current end of tape where you could punch in a subroutine and a return statement.
If all else failed you'd create a "patch tape" that was read after the original tape and overwrote memory locations.
It was all very convenient since you could "single step" the program from the front panel and watch the registers change.
Life got really sweet when the new teletype had a reader/punch.
Good times.