| /* This tests the somewhat obscure 32-bit Intel aam and aad instructions */ |
| /* by Vince Weaver (vince _at_ deater.net ) */ |
| |
| #include <stdio.h> |
| |
| int parity(int v) { |
| |
| int i; |
| int p = 1; |
| |
| for (i = 0; i < 8; i++) |
| p ^= (1 & (v >> i)); |
| return p; |
| } |
| |
| int main(int argc, char **argv) { |
| |
| printf("test begins\n"); |
| unsigned short i,out; |
| unsigned int flags; |
| int cf __attribute__((unused)),pf,af __attribute__((unused)),zf,sf; |
| int of __attribute__((unused)); |
| |
| /* test AAM */ |
| |
| for(i=0;i<65535;i++) { |
| // printf("%d, %d, %d\n",i,(i&0xff)/10,(i&0xff)%10); |
| out=i; |
| __asm__ __volatile__ ("mov %2 ,%%ax\n" |
| "aam\n" |
| "pushf\n" |
| "mov %%ax, %0\n" |
| "pop %%eax\n" |
| "mov %%eax, %1\n" |
| :"=r"(out), "=r"(flags) /* outputs */ |
| :"r"(out) /* input */ |
| :"%eax" /* clobbered */ |
| ); |
| cf=!!(flags&0x1); |
| pf=!!(flags&0x4); |
| af=!!(flags&0x10); |
| zf=!!(flags&0x40); |
| sf=!!(flags&0x80); |
| of=!!(flags&0x800); |
| |
| // printf("%d, %d, %d, ",i,(out>>8)&0xff,out&0xff); |
| // printf("%x CF=%d PF=%d AF=%d ZF=%d SF=%d OF=%d\n", |
| // flags,cf,pf,af,zf,sf,of); |
| |
| if (zf && ((out&0xff)!=0)) { |
| printf("Error with aam (zf)!\n"); |
| } |
| if (pf != parity(out&0xff)) { |
| printf("Error with aam (pf)!\n"); |
| } |
| if (sf != !!(out&0x80)) { |
| printf("Error with aam (sf)!\n"); |
| } |
| |
| |
| if ( ((out>>8)&0xff) != ((i&0xff)/10)) { |
| printf("Error with aam!\n"); |
| } |
| if ( (out&0xff) != ((i&0xff)%10)) { |
| printf("Error with aam!\n"); |
| } |
| |
| } |
| |
| /* test AAD */ |
| |
| for(i=0;i<65535;i++) { |
| // printf("%x, %d\n",i, ((((i>>8)&0xff)*10)+(i&0xff))&0xff ); |
| out=i; |
| __asm__ __volatile__ ("mov %2 ,%%ax\n" |
| "aad\n" |
| "pushf\n" |
| "mov %%ax, %0\n" |
| "pop %%eax\n" |
| "mov %%eax, %1\n" |
| :"=r"(out), "=r"(flags) /* outputs */ |
| :"r"(out) /* input */ |
| :"%eax" /* clobbered */ |
| ); |
| |
| cf=!!(flags&0x1); |
| pf=!!(flags&0x4); |
| af=!!(flags&0x10); |
| zf=!!(flags&0x40); |
| sf=!!(flags&0x80); |
| of=!!(flags&0x800); |
| |
| // printf("%x, %d ",i,out); |
| // printf("%x CF=%d PF=%d AF=%d ZF=%d SF=%d OF=%d\n", |
| // flags,cf,pf,af,zf,sf,of); |
| |
| if (zf && ((out&0xff)!=0)) { |
| printf("Error with aad (zf)!\n"); |
| } |
| if (pf != parity(out&0xff)) { |
| printf("Error with aad (pf)!\n"); |
| } |
| if (sf != !!(out&0x80)) { |
| printf("Error with aad (sf) %d %d!\n",sf,!!(out&0x80)); |
| } |
| |
| if ( out != ( ((((i>>8)&0xff)*10)+(i&0xff))&0xff) ) { |
| printf("Error with aad!\n"); |
| } |
| } |
| |
| printf("test completed\n"); |
| return 0; |
| |
| } |