# # rep, repe (repz) and repne (repnz) prefixed string instructions # only count as one instruction, even though they repeat many times # This test makes sure the bbv plugin counts these instructions properly # The answer is validated to hw perf counters. # .globl _start _start: cld # we want these to happen forward #=================================== # Check varied order of the size prefix # with the rep prefix. Older binutils # did this one way, newer binutils the other #=================================== size_prefix: # test 16-bit load mov $8192, %ecx mov $buffer1, %esi # set source .byte 0x66, 0xf3, 0xad # lodsw mov $8192, %ecx mov $buffer1, %esi # set source .byte 0xf3, 0x66, 0xad # lodsw #=================================== # Load and Store Instructions #=================================== loadstore: xor %eax, %eax mov $0xd, %al # set eax to d # test 8-bit store mov $16384, %ecx mov $buffer1, %edi # set destination rep stosb # store d 16384 times, auto-increment # test 8-bit load mov $16384, %ecx mov $buffer1, %esi # set source rep lodsb # load byte 16384 times, auto-increment cmp $0xd,%al # if we loaded wrong value jne print_error # print an error # test 16-bit store mov $0x020d,%ax # store 0x020d mov $8192, %ecx mov $buffer1, %edi # set destination rep stosw # store 8192 times, auto-increment # test 16-bit load mov $8192, %ecx mov $buffer1, %esi # set source rep lodsw # load 8192 times, auto-increment cmp $0x020d,%ax # if we loaded wrong value jne print_error # print an error # test 32-bit store mov $0x0feb1378,%eax # store 0x0feb1378 mov $4096, %ecx mov $buffer1, %edi # set destination rep stosl # store 4096 times, auto-increment # test 32-bit load mov $4096, %ecx mov $buffer1, %esi # set source rep lodsl # load 4096 times, auto-increment cmp $0x0feb1378,%eax # if we loaded wrong value jne print_error # print an error #============================= # Move instructions #============================= moves: # test 8-bit move mov $16384, %ecx mov $buffer1, %esi mov $buffer2, %edi rep movsb # test 16-bit move mov $8192, %ecx mov $buffer2, %esi mov $buffer1, %edi rep movsw # test 32-bit move mov $4096, %ecx mov $buffer1, %esi mov $buffer2, %edi rep movsl #================================== # Compare equal instructions #================================== compare_equal: # first set up the areas to compare mov $0xa5a5a5a5,%eax mov $buffer1, %edi mov $4096, %ecx rep stosl mov $0xa5a5a5a5,%eax mov $buffer2, %edi mov $4096, %ecx rep stosl # test 8-bit mov $buffer1,%esi mov $buffer2,%edi mov $16384, %ecx repe cmpsb jnz print_error # test 16-bit mov $buffer1,%esi mov $buffer2,%edi mov $8192, %ecx repe cmpsw jnz print_error # test 32-bit mov $buffer1,%esi mov $buffer2,%edi mov $4096, %ecx repe cmpsl jnz print_error #================================== # Compare not equal instructions #================================== compare_noteq: # change second buffer mov $0x5a5a5a5a,%eax mov $buffer2, %edi mov $4096, %ecx rep stosl # test 8-bit mov $buffer1,%esi mov $buffer2,%edi mov $16384, %ecx repne cmpsb je print_error # test 16-bit mov $buffer1,%esi mov $buffer2,%edi mov $8192, %ecx repne cmpsw je print_error # test 32-bit mov $buffer1,%esi mov $buffer2,%edi mov $4096, %ecx repne cmpsl je print_error #==================================== # Check scan equal instruction #==================================== # test 8-bit mov $0xa5,%al mov $buffer1,%edi mov $16384, %ecx repe scasb jnz print_error # test 16-bit mov $0xa5a5,%ax mov $buffer1,%edi mov $8192, %ecx repe scasw jnz print_error # test 32-bit mov $0xa5a5a5a5,%eax mov $buffer1,%edi mov $4096, %ecx repe scasl jnz print_error #==================================== # Check scan not-equal instruction #==================================== # test 8-bit mov $0xa5,%al mov $buffer2,%edi mov $16384, %ecx repne scasb jz print_error # test 16-bit mov $0xa5a5,%ax mov $buffer2,%edi mov $8192, %ecx repne scasw jz print_error # test 32-bit mov $0xa5a5a5a5,%eax mov $buffer2,%edi mov $4096, %ecx repne scasl jz print_error jmp exit # no error, skip to exit print_error: mov $4, %eax # Write syscall #ifdef VGO_darwin pushl $1 pushl $error_string pushl $16 #else mov $1, %ebx # print to stdout mov $error_string, %ecx # string to print mov $16, %edx # strlen #endif int $0x80 # call syscall #================================ # Exit #================================ exit: #ifdef VGO_darwin xor %ebx,%ebx # we return 0 #else pushl $0 # we return 0 #endif xor %eax,%eax inc %eax # put exit syscall number (1) in eax int $0x80 # and exit .data error_string: .asciz "Error detected!\n" #.bss .lcomm buffer1, 16384 .lcomm buffer2, 16384