Here is a short example of the flexibility of MASM with code generation. ZIP file attached. MASM is a MACRO assembler and it is not trying to be a C compiler, CL does that just fine.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include64\masm64rt.inc
.data
MyString db "Once upon a time, the birds chewed lime and monkeys chewed tobacco",0
pStr dq MyString
.code
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
entry_point proc
USING r12,r13
LOCAL lstr :QWORD
SaveRegs
rcall getlen,pStr
mov lstr, rax
mov rcx, rax
rcall show1,rcx
rcall show2,lstr
rcall show3,lstr
RestoreRegs
.exit
entry_point endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
PROCALIGN
show1 proc
rcall MessageBox,0,str$(rcx),"PROCALIGN",MB_OK
ret
show1 endp
STACKFRAME
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
show2 proc
rcall MessageBox,0,str$(rcx),"STACKFRAME",MB_OK
ret
show2 endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
ALTSTACKFRAME 128, 64
show3 proc
rcall MessageBox,0,str$(rcx),"ALTSTACKFRAME",MB_OK
ret
show3 endp
STACKFRAME
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
NOSTACKFRAME
getlen proc
mov rax, rcx
sub rax, 1
lbl:
REPEAT 3
add rax, 1
movzx r10, BYTE PTR [rax]
test r10, r10
jz lbl1
ENDM
add rax, 1
movzx r10, BYTE PTR [rax]
test r10, r10
jnz lbl
lbl1:
sub rax, rcx
ret
getlen endp
STACKFRAME
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end
; .text:0000000140001000 C8800000 enter 0x80, 0x0
; .text:0000000140001004 4881EC80000000 sub rsp, 0x80
; .text:000000014000100b 4C896588 mov qword ptr [rbp-0x78], r12
; .text:000000014000100f 4C896D90 mov qword ptr [rbp-0x70], r13
; .text:0000000140001013 488B0D85100000 mov rcx, qword ptr [0x14000209f]
; .text:000000014000101a E8F5000000 call sub_140001114
; .text:000000014000101a
; .text:000000014000101f 48894580 mov qword ptr [rbp-0x80], rax
; .text:0000000140001023 488BC8 mov rcx, rax
; .text:0000000140001026 488BC9 mov rcx, rcx
; .text:0000000140001029 E827000000 call sub_140001055
; .text:0000000140001029
; .text:000000014000102e 488B4D80 mov rcx, qword ptr [rbp-0x80]
; .text:0000000140001032 E85C000000 call sub_140001093
; .text:0000000140001032
; .text:0000000140001037 488B4D80 mov rcx, qword ptr [rbp-0x80]
; .text:000000014000103b E892000000 call sub_1400010d2
; .text:000000014000103b
; .text:0000000140001040 4C8B6588 mov r12, qword ptr [rbp-0x78]
; .text:0000000140001044 4C8B6D90 mov r13, qword ptr [rbp-0x70]
; .text:0000000140001048 48C7C100000000 mov rcx, 0x0
; .text:000000014000104f FF1533110000 call qword ptr [ExitProcess]
; .text:000000014000104f
; ; --------------------------------------------------------------------------
; ; sub_140001055
; ; --------------------------------------------------------------------------
; sub_140001055 proc
; .text:0000000140001055 4883EC08 sub rsp, 8
; .text:0000000140001059 488BC9 mov rcx, rcx
; .text:000000014000105c 488B1544100000 mov rdx, qword ptr [0x1400020a7]
; .text:0000000140001063 49C7C00A000000 mov r8, 0xa
; .text:000000014000106a FF1538110000 call qword ptr [_i64toa]
; .text:000000014000106a
; .text:0000000140001070 49C7C100000000 mov r9, 0x0
; .text:0000000140001077 4C8B053C100000 mov r8, qword ptr [0x1400020ba]
; .text:000000014000107e 488B1522100000 mov rdx, qword ptr [0x1400020a7]
; .text:0000000140001085 4833C9 xor rcx, rcx
; .text:0000000140001088 FF150A110000 call qword ptr [MessageBoxA]
; .text:0000000140001088
; .text:000000014000108e 4883C408 add rsp, 8
; .text:0000000140001092 C3 ret
; sub_140001055 endp
;
; ; --------------------------------------------------------------------------
; ; sub_140001093
; ; --------------------------------------------------------------------------
; sub_140001093 proc
; .text:0000000140001093 C8800000 enter 0x80, 0x0
; .text:0000000140001097 4883EC60 sub rsp, 0x60
; .text:000000014000109b 488BC9 mov rcx, rcx
; .text:000000014000109e 488B151D100000 mov rdx, qword ptr [0x1400020c2]
; .text:00000001400010a5 49C7C00A000000 mov r8, 0xa
; .text:00000001400010ac FF15F6100000 call qword ptr [_i64toa]
; .text:00000001400010ac
; .text:00000001400010b2 49C7C100000000 mov r9, 0x0
; .text:00000001400010b9 4C8B051B100000 mov r8, qword ptr [0x1400020db]
; .text:00000001400010c0 488B15FB0F0000 mov rdx, qword ptr [0x1400020c2]
; .text:00000001400010c7 4833C9 xor rcx, rcx
; .text:00000001400010ca FF15C8100000 call qword ptr [MessageBoxA]
; .text:00000001400010ca
; .text:00000001400010d0 C9 leave
; .text:00000001400010d1 C3 ret
; sub_140001093 endp
;
; ; --------------------------------------------------------------------------
; ; sub_1400010d2
; ; --------------------------------------------------------------------------
; sub_1400010d2 proc
; .text:00000001400010d2 55 push rbp
; .text:00000001400010d3 488BEC mov rbp, rsp
; .text:00000001400010d6 4881EC80000000 sub rsp, 0x80
; .text:00000001400010dd 488BC9 mov rcx, rcx
; .text:00000001400010e0 488B15FC0F0000 mov rdx, qword ptr [0x1400020e3]
; .text:00000001400010e7 49C7C00A000000 mov r8, 0xa
; .text:00000001400010ee FF15B4100000 call qword ptr [_i64toa]
; .text:00000001400010ee
; .text:00000001400010f4 49C7C100000000 mov r9, 0x0
; .text:00000001400010fb 4C8B05FC0F0000 mov r8, qword ptr [0x1400020fe]
; .text:0000000140001102 488B15DA0F0000 mov rdx, qword ptr [0x1400020e3]
; .text:0000000140001109 4833C9 xor rcx, rcx
; .text:000000014000110c FF1586100000 call qword ptr [MessageBoxA]
; .text:000000014000110c
; .text:0000000140001112 C9 leave
; .text:0000000140001113 C3 ret
; sub_1400010d2 endp