Joining strings in Zero Assembly
hello-concat.zasm prints two pieces of text, then joins them with a space. Joining strings is called concatenation.
1. Import helper functions
#IMPORT msvcrt.dll, puts, strcpy, strcat, exit
This loads functions from a Windows library:
| Function | Job |
|---|---|
puts |
Print text and move to the next line. |
strcpy |
Copy text into another memory area. |
strcat |
Add text to the end of an existing string. |
exit |
Finish the program. |
2. Make room for the joined text
sub esp, 64
lea esi, [esp]
This reserves 64 bytes on the stack, a temporary storage area. esi is a
CPU register: a small storage location holding the buffer’s address.
The final string needs 21 bytes, including its ending marker.
3. Store the words
call hello_ready
hello_text:
db 72, 101, 108, 108, 111, 0
hello_ready:
pop edi
db stores bytes. Here, the numbers are ASCII codes spelling Hello.
The final 0 marks the end; it is not the character 0.
call jumps over the text and saves its address on the stack. pop edi takes
that address into edi. The program repeats this trick for Zero Assembly!,
storing its address in ebx.
4. Print each string
push edi
call [puts]
add esp, 4
push supplies the string’s address to puts. call [puts] calls the imported
function through its stored address. Afterward, add esp, 4 removes that argument
from the stack.
The program repeats this for the second string.
5. Build and print the combined string
The next calls change the buffer in three steps:
strcpy → Hello
strcat → Hello[space]
strcat → Hello Zero Assembly!
For these two-argument functions, the source address is pushed first, then the
destination address. add esp, 8 removes both arguments afterward.
The program prints the buffer with puts, then calls exit with 0 to signal
success. The joined sentence is built while the program runs.
Try it
From the repository root, after building the compiler:
./zero.exe run samples/hello-concat.zasm
Output:
Hello
Zero Assembly!
Hello Zero Assembly!
Reference
A mnemonic is a short name for a CPU instruction. This table covers the instructions and assembler directives used in the sample.
| Mnemonic | Name | What it does | Example from the sample |
|---|---|---|---|
sub |
Subtract | Subtracts a number. Here, moving the stack pointer down reserves 64 bytes of storage. | sub esp, 64 |
lea |
Load effective address | Saves a memory address in a register. It does not read the text stored there. | lea esi, [esp] |
call |
Call a function or label | Saves the return address on the stack, then jumps to the requested code. | call hello_ready |
pop |
Take from the stack | Takes the top value off the stack and puts it in a register. | pop edi |
push |
Place on the stack | Places a value on the stack. This sample uses it to pass function arguments. | push edi |
add |
Add | Adds a number. Here, moving the stack pointer up removes a used argument. | add esp, 4 |
db |
Define byte | Stores raw bytes in the program, such as ASCII letters and an ending zero. This is an assembler directive. | db 32, 0 stores a space and its ending zero. |
#IMPORT |
Import functions | Declares which functions the program needs from a DLL. This is an assembler directive. | #IMPORT msvcrt.dll, puts, strcpy, strcat, exit |
Names ending in :, such as hello_ready:, are labels that name locations
in the program. Names such as esp, esi, and edi are registers, not
instructions. esp holds the address of the top of the stack.