I’ve been working on some of the instruction tests in vial, and I wanted to test the implementation of LOOP variants. My objective was to make sure the vial version is identical to the real CPU version (as discussed here). To achieve this, I had to cover all of the essential behaviors of LOOP.
Well, using the framework Gil and I wrote, I hacked up some code that should cover the relevant cases:
code_template = """ mov edx, ecx ; control the start zf mov ecx, eax ; number of iterations mov eax, 0 ; will hold the result, also an iteration counter loop_start: cmp eax, ebx ; check if we need to change zf setz dh xor dh, dl ; if required, invert zf inc eax ; count the iteration cmp dh, 0 ; set zf loop%s loop_start """ for loop_kind in ['','z','nz']: code_text = code_template % loop_kind c = FuncObject(code_text) for start_zf_value in [0,1]: for num_iters in [1,4,10]: for when_zf_changes in [1,2,15]: c(num_iters, when_zf_changes, start_zf_value) c.check()
Note that c(…) executes the code both on vial’s VM, and on the real cpu. c.check() compares their return value (EAX) and flags after the execution. I also wanted to avoid other kinds of jumps in this test.
To check that the code ran the same number of times, I returned EAX as the number of iterations.
All the games with edx are there to make sure that I’m testing different zf conditions.
The challenge for today:
Can you write a shorter assembly snippet that tests the same thing?