/*Asm labels can only be defined once in a task. <F5> will spawn a new task each time, so you don't get redefine error, like when repeatedly #including it from the cmd line. */ //This is to demo global variable access. //Globals defined elsewhere can accessed too, like counts.jiffies. I64 global_ona = Freq2Ona(400), global_ona_step = 10, global_ona_base = Freq2Ona(100); asm { //Opcodes are slightly different to make writing the x86_64 assembler easier. //See ::/Compiler/OpCodes.DD. JIFFIES_MESSAGE: DU8 "Jiffies:", 0; //See ::/Kernel/StrA.ZC and ::/Kernel/KUtils.ZC. _BEEPS2:: //You can clobber RAX,RBX,RCX,RDX,R8,R9. The compiler expects that. //See REGG_CLOBBERED and REGG_STACK_TMP. PUSH RBP MOV RBP, RSP MOV RCX, U64 SF_ARG1[RBP] //SF_ARG1 PUSH U64 [&counts.jiffies] @@05: PUSH RCX //U0 Beep(I8 ona=62, Bool busy=FALSE) PUSH FALSE //Do not busy (spin) wait PUSH U64 [&global_ona] //evaluated at run time CALL &Beep POP RCX LOOP @@05 PUSH RSI //See REGG_LOCAL_VARS & REGG_LOCAL_NON_PTR_VARS MOV RSI, JIFFIES_MESSAGE CALL PUT_STR POP RSI POP RAX SUB RAX, U64 [&counts.jiffies] NEG RAX CALL PUT_HEX_U64 MOV RAX, '\n' CALL PUT_CHARS POP RBP RET1 8 } //The convention is to put an underscore //on C callable asm routines. _extern _BEEPS2 U0 Beeps2(I64 count); U0 AsmAndC2() { I64 reg R15 i; i = I64Get("$PURPLE$\n\nNum of beeps 1-5 (%d):$FG$", 3, 1, 5); Beeps2(i); asm { LIST //You can clobber RAX,RBX,RCX,RDX, but preserve the rest. MOV RCX, R15 //You can clobber RAX,RBX,RCX,RDX. Preserve the rest. @@05: PUSH RCX //U0 Sound(I8 ona); MOV RAX, RCX //ona=loop*10+100.0Hz IMUL2 RAX, global_ona_step //Intentionally evaluated at compile time ADD RAX, U64 [&global_ona_base] //Intentionally evaluated at run time PUSH RAX CALL &Sound //We can skip IMPORT with & if JIT compiling. MOV RCX, counts.time_stamp_freq >> 3 //JIT Const. Simple delay loop. @@10: LOOP @@10 POP RCX LOOP @@05 } Sound; } AsmAndC2;