;unsigned char *putVLQ(unsigned value, unsigned char *dest) // write a VLQ ;{ // (see Standard MIDI-File Format Spec. 1.1) ; unsigned buffer = value & 0x7f; ; while ((value >>= 7) > 0) { ; buffer <<= 8; ; buffer |= 0x80; ; buffer += value & 0x7f; ; } ; for ( ; ; ) { ; *dest++ = (unsigned char)buffer; ; if (buffer & 0x80) ; buffer >>= 8; ; else ; return dest; ; } ;} option prologue:none, epilogue:none .code putvlq proc _putvlq proc ; "value" is passed in RDI, "dest" - in RSI XCHG RSI,RDI ; "value" = RSI, STOSB makes "dest" go in RDI MOV EAX,7F7F7F7FH ; a buffer mask (in EAX because of STOSB) PDEP EAX,ESI,EAX ; extend "value"s significant bits into buffer LZCNT ECX,EAX ; CL = 32 - number of the significant bytes OR EAX,80808000H ; set bit markers for a byte that's not final AND CL,18H ; shift the buffer by a multiple of 8 bits SHL EAX,CL ; (if "value" = 0, there will be no shift) BSWAP EAX ; writing starts from the most significant byte .repeat ; for ( ; ; ) { STOSB ; *dest++ = (unsigned char)buffer; SHR EAX,8 ;___ ___ if (buffer & 0x80) .until (!carry?) ;___X___ buffer >>= 8; XCHG RAX,RDI ; else return dest; RET ; } _putvlq endp putvlq endp end