.intel_syntax noprefix
.global main
main:
sub esp, 12
mov [esp + 8], ebx
xor ebx, ebx
test_loop:
mov eax, [in + 4 * ebx]
mov dword ptr [esp], eax
call bitstuffing
mov [esp + 8], eax
cmp eax, [verify + 4 * ebx]
mov dword ptr [esp], offset ok
je got_fmt
mov dword ptr [esp], offset error
got_fmt:
mov eax, [in + 4 * ebx]
mov [esp + 4], eax
inc ebx
cmp ebx, 7
jb test_loop
mov ebx, [esp + 8]
add esp, 12
xor eax, eax
ret
bitstuffing:
push ebp
mov ebp, esp
push ebx
mov cl, 32 # 32 bits to go
xor eax, eax # the output
mov edx, [ebp + 8] # the input
xor bl, bl # the run count
next_bit:
dec cl # more bits?
js done # no
shl edx, 1 # consume from the input into CF
rcl eax, 1 # copy to output from CF
test bl, bl # first bit always matches
jz match
test al, 3 # do we have 00 or 11 in the low 2 bits?
jnp reset # no, start counting again
match:
inc bl
cmp bl, 5 # did 5 bits match?
jb next_bit # no, keep going
dec cl # space for stuffed bit?
js done # no
mov ebx, eax # make a copy
and ebx, 1 # isolate LSB
xor ebx, 1 # flip it
shl eax, 1 # make space for it
or eax, ebx # stuff it
reset:
mov bl, 1 # already have length 1
jmp next_bit
done:
pop ebx
mov esp, ebp
pop ebp
ret
.data
ok: .string "OK: 0x%08x => 0x%08x\n"
error: .string "ERROR: 0x%08x => 0x%08x\n"
in: .int 0xFFFFFFFF, 0x00000000, 0x0F0F0F0F, 0x0F0F0F00, 0x0F0F0000, 0xAAAA0000, 0x07878000
verify: .int 0xFBEFBEFB, 0x04104104, 0x0F0F0F0F, 0x0F0F0F04, 0x0F0F0410, 0xAAAA0820, 0x07C1F041
ICAgIC5pbnRlbF9zeW50YXggbm9wcmVmaXgKICAgIC5nbG9iYWwgbWFpbgogICAgbWFpbjoKICAgICAgICBzdWIgZXNwLCAxMgogICAgICAgIG1vdiBbZXNwICsgOF0sIGVieAogICAgICAgIHhvciBlYngsIGVieAogICAgCiAgICB0ZXN0X2xvb3A6CiAgICAgICAgbW92IGVheCwgW2luICsgNCAqIGVieF0KICAgICAgICBtb3YgZHdvcmQgcHRyIFtlc3BdLCBlYXgKICAgICAgICBjYWxsIGJpdHN0dWZmaW5nCiAgICAgICAgbW92IFtlc3AgKyA4XSwgZWF4CiAgICAgICAgY21wIGVheCwgW3ZlcmlmeSArIDQgKiBlYnhdCiAgICAgICAgbW92IGR3b3JkIHB0ciBbZXNwXSwgb2Zmc2V0IG9rCiAgICAgICAgamUgZ290X2ZtdAogICAgICAgIG1vdiBkd29yZCBwdHIgW2VzcF0sIG9mZnNldCBlcnJvcgogICAgZ290X2ZtdDoKICAgICAgICBtb3YgZWF4LCBbaW4gKyA0ICogZWJ4XQogICAgICAgIG1vdiBbZXNwICsgNF0sIGVheAogICAgICAgIGNhbGwgcHJpbnRmCiAgICAgICAgaW5jIGVieAogICAgICAgIGNtcCBlYngsIDcKICAgICAgICBqYiB0ZXN0X2xvb3AKICAgIAogICAgICAgIG1vdiBlYngsIFtlc3AgKyA4XQogICAgICAgIGFkZCBlc3AsIDEyCiAgICAgICAgeG9yIGVheCwgZWF4CiAgICAgICAgcmV0CiAgICAKICAgIGJpdHN0dWZmaW5nOgogICAgICAgIHB1c2ggZWJwCiAgICAgICAgbW92IGVicCwgZXNwCiAgICAgICAgcHVzaCBlYngKICAgIAogICAgICAgIG1vdiBjbCwgMzIgICAgICAgICAjIDMyIGJpdHMgdG8gZ28KICAgICAgICB4b3IgZWF4LCBlYXggICAgICAgIyB0aGUgb3V0cHV0CiAgICAgICAgbW92IGVkeCwgW2VicCArIDhdICMgdGhlIGlucHV0CiAgICAgICAgeG9yIGJsLCBibCAgICAgICAgICMgdGhlIHJ1biBjb3VudAogICAgbmV4dF9iaXQ6CiAgICAgICAgZGVjIGNsICAgICAgICAgICAgICMgbW9yZSBiaXRzPwogICAgICAgIGpzIGRvbmUgICAgICAgICAgICAjIG5vCiAgICAgICAgc2hsIGVkeCwgMSAgICAgICAgICMgY29uc3VtZSBmcm9tIHRoZSBpbnB1dCBpbnRvIENGCiAgICAgICAgcmNsIGVheCwgMSAgICAgICAgICMgY29weSB0byBvdXRwdXQgZnJvbSBDRgogICAgICAgIHRlc3QgYmwsIGJsICAgICAgICAjIGZpcnN0IGJpdCBhbHdheXMgbWF0Y2hlcwogICAgICAgIGp6IG1hdGNoCiAgICAgICAgdGVzdCBhbCwgMyAgICAgICAgICMgZG8gd2UgaGF2ZSAwMCBvciAxMSBpbiB0aGUgbG93IDIgYml0cz8KICAgICAgICBqbnAgcmVzZXQgICAgICAgICAgIyBubywgc3RhcnQgY291bnRpbmcgYWdhaW4KICAgIG1hdGNoOgogICAgICAgIGluYyBibAogICAgICAgIGNtcCBibCwgNSAgICAgICAgICAjIGRpZCA1IGJpdHMgbWF0Y2g/CiAgICAgICAgamIgbmV4dF9iaXQgICAgICAgICMgbm8sIGtlZXAgZ29pbmcKICAgICAgICBkZWMgY2wgICAgICAgICAgICAgIyBzcGFjZSBmb3Igc3R1ZmZlZCBiaXQ/CiAgICAgICAganMgZG9uZSAgICAgICAgICAgICMgbm8KICAgICAgICBtb3YgZWJ4LCBlYXggICAgICAgIyBtYWtlIGEgY29weQogICAgICAgIGFuZCBlYngsIDEgICAgICAgICAjIGlzb2xhdGUgTFNCCiAgICAgICAgeG9yIGVieCwgMSAgICAgICAgICMgZmxpcCBpdAogICAgICAgIHNobCBlYXgsIDEgICAgICAgICAjIG1ha2Ugc3BhY2UgZm9yIGl0CiAgICAgICAgb3IgZWF4LCBlYnggICAgICAgICMgc3R1ZmYgaXQKICAgIHJlc2V0OgogICAgICAgIG1vdiBibCwgMSAgICAgICAgICAjIGFscmVhZHkgaGF2ZSBsZW5ndGggMQogICAgICAgIGptcCBuZXh0X2JpdAogICAgCiAgICBkb25lOgogICAgICAgIHBvcCBlYngKICAgICAgICBtb3YgZXNwLCBlYnAKICAgICAgICBwb3AgZWJwCiAgICAgICAgcmV0CiAgICAKICAgIC5kYXRhCiAgICBvazogLnN0cmluZyAiT0s6IDB4JTA4eCA9PiAweCUwOHhcbiIKICAgIGVycm9yOiAuc3RyaW5nICJFUlJPUjogMHglMDh4ID0+IDB4JTA4eFxuIgogICAgaW46IC5pbnQgMHhGRkZGRkZGRiwgMHgwMDAwMDAwMCwgMHgwRjBGMEYwRiwgMHgwRjBGMEYwMCwgMHgwRjBGMDAwMCwgMHhBQUFBMDAwMCwgMHgwNzg3ODAwMAogICAgdmVyaWZ5OiAuaW50IDB4RkJFRkJFRkIsIDB4MDQxMDQxMDQsIDB4MEYwRjBGMEYsIDB4MEYwRjBGMDQsIDB4MEYwRjA0MTAsIDB4QUFBQTA4MjAsIDB4MDdDMUYwNDE=