Để dịch các cấu trúc điều khiển như if, while sang bytecode, trình biên dịch cần các lệnh nhãn (label) và nhảy (jump). Mở rộng máy ảo ngăn xếp với bộ lệnh:
PUSH x: đẩy số nguyên x vào ngăn xếp.ADD, SUB, MUL, DIV: như bài toán máy ảo cơ bản (b là đỉnh, a là phần tử dưới; DIV làm tròn phần nguyên về 0).DUP: nhân đôi phần tử ở đỉnh ngăn xếp (không lấy ra).POP: bỏ phần tử ở đỉnh ngăn xếp.PRINT: in ra giá trị đỉnh ngăn xếp (không lấy ra).LABEL name: đánh dấu vị trí này bằng tên name — bản thân lệnh này không làm gì khi thực thi.JMP name: nhảy vô điều kiện tới vị trí lệnh LABEL name.JZ name: lấy ra phần tử ở đỉnh ngăn xếp; nếu giá trị đó bằng 0 thì nhảy tới LABEL name, ngược lại thực hiện lệnh kế tiếp bình thường.JNZ name: lấy ra phần tử ở đỉnh ngăn xếp; nếu giá trị đó khác 0 thì nhảy tới LABEL name, ngược lại thực hiện lệnh kế tiếp bình thường.HALT: dừng thực thi ngay lập tức.Máy ảo bắt đầu thực thi từ lệnh đầu tiên của chương trình. Chương trình kết thúc khi gặp HALT hoặc khi con trỏ lệnh vượt quá dòng lệnh cuối cùng. Mỗi tên nhãn trong chương trình là duy nhất. Dữ liệu đảm bảo chương trình luôn kết thúc (không lặp vô hạn) và không xảy ra thiếu hụt ngăn xếp.
Ví dụ: chương trình
PUSH 3
LABEL loop
DUP
PRINT
PUSH 1
SUB
DUP
JNZ loop
POP
in ra lần lượt 3, 2, 1 — một vòng lặp đếm ngược in giá trị hiện tại rồi giảm 1, lặp lại khi giá trị còn khác 0.
Dòng đầu chứa số nguyên n (1≤n≤1000). n dòng tiếp theo là các lệnh trong bộ lệnh nêu trên. Tổng số lệnh thực thi (kể cả lặp qua nhãn nhiều lần) không vượt quá 200000.
Mỗi giá trị được PRINT in ra trên một dòng riêng, theo đúng thứ tự thực thi. Nếu không có PRINT nào được thực thi, không in gì.
Ví dụ:
Đầu vào:
8
PUSH 0
JZ skip
PUSH 99
PRINT
LABEL skip
PUSH 1
PRINT
HALT
Đầu ra:
1
Đầu vào:
9
PUSH 3
LABEL loop
DUP
PRINT
PUSH 1
SUB
DUP
JNZ loop
POP
Đầu ra:
3
2
1
Đang tải editor...