1: ; File name: mmx_brightening.asm (requires NASM 0.97) 2: 3: bits 32 ; 32 bit protected mode programming. 4: section .text ; Start code segment. 5: 6: ;----------------------------------------------------------------------- 7: ; C prototype: int cpuid_support(void); 8: ; Returns 1 if the current x86 processor supports the CPUID instruction, 9: ; otherwise returns 0. 10: global cpuid_support ; Export cpuid_support label. 11: align 16 12: cpuid_support: 13: ;;; Try to modify bit 21 in EFLAGS register. 14: pushf ; Push EFLAGS register into the stack. 15: pop ecx ; Pop stack. ECX has a copy of EFLAGS. 16: mov edx, ecx ; Put another copy of EFLAGS in EDX. 17: xor ecx, 0x00200000 ; Complement bit 21 of ECX. 18: push ecx ; Push ECX into the stack. 19: popf ; Pop stack. EFLAGS should have a copy of ECX. 20: 21: ;;; Check if bit 21 was successfully changed in EFLAGS register. 22: xor eax, eax ; EAX = 0, default return value (failure). 23: pushf ; Push EFLAGS register again into the stack. 24: pop ecx ; Pop stack. ECX has a copy of new EFLAGS. 25: cmp ecx, edx ; Are ECX and EDX the same? 26: je .no_CPUID_Support ; Jump if they are (there's no CPUID support). 27: mov eax, 1 ; EAX = 1, means success. 28: .no_CPUID_Support: 29: ret ; End routine, EAX has return value. 30: 31: ;------------------------------------------------------------------------- 32: ; C prototype: int mmx_support(void); 33: ; Returns 1 if the current x86 processor supports MMX technology, otherwise 34: ; returns 0. 35: global mmx_support ; Export mmx_support label. 36: align 16 37: mmx_support: 38: call cpuid_support ; Check if it's OK to use CPUID. 39: test eax, eax ; Is EAX = 0? 40: jz .no_MMX_Support ; Jump if it is (there's no CPUID support). 41: 42: ; Get CPU feature information. 43: mov eax, 1 44: cpuid 45: xor eax, eax ; EAX = 0, default return value (failure). 46: test edx, 0x00800000 ; Is bit 23 set? 47: jz .no_MMX_Support ; Jump if it isn't (there's no MMX support). 48: mov eax, 1 ; EAX = 1, means success. 49: .no_MMX_Support: 50: ret ; End routine, EAX has return value. 51: 52: ;------------------------------------------------------------------------- 53: ; C prototype: void brightening( 54: ; unsigned char * BK_vector, 55: ; unsigned char * bitmap, 56: ; size_t iterations 57: ; ); 58: ; Image brightening algorithm using MMX technology. 59: global brightening ; Export brightening label. 60: align 16 61: brightening: 62: push ebp ; Must preserve original EBP register. 63: mov ebp, esp ; Initialize EBP in order to access parameters. 64: 65: mov eax, [ebp+8] ; EAX = pointer to the brightening constant vector. 66: movq mm0, [eax] ; Load in MM0 the brightening constant vector. 67: 68: mov edx, [ebp+12] ; EDX = pointer to first element of bitmap array. 69: mov ecx, [ebp+16] ; ECX = number of iterations. 70: xor eax, eax ; EAX = 0. EAX is an index to the bitmap array. 71: 72: align 16 73: .repeat 74: movq mm1, [edx+eax*8]; Load MM1 with next 8 bytes. 75: paddusb mm1, mm0 ; Add into MM1 8 bytes with unsigned saturation. 76: movq [edx+eax*8], mm1; Copy back to memory the result. 77: inc eax ; EAX = EAX + 1. 78: dec ecx ; ECX = ECX - 1. 79: jnz .repeat ; Repeat while ECX != 0. 80: 81: emms ; Empty MMX state. 82: 83: pop ebp ; Restore original EBP register. 84: ret ; End routine.