p = (uint16_t)ata->ata_io_base + 2;
addr = (byte_t *)(&aa.aa_low);
outb(p++,(byte_t)(0xFF & (byte_t)sn));
outb(p++,*addr++);
outb(p++,*addr++);
outb(p++,*addr++);
outb(p++,*addr);
kprintf("send ata command.port:%04X cmd:%02X ",p,cmd);
//outb(p, cmd);
__asm{
mov dx,p
mov al,cmd
out dx,al
}
kprintf("OK!\n");
上面的代码在跑的时候,有时候会出现非法指令的异常,实在找不到在哪里出现的错误。跑出来的结果见下图:
看输出的结果非常奇怪,eip居然和ebx的内容一样,但是对应的反汇编根本没有使用ebx的间接跳转,而且如果有的话,之前使用到这个代码的地方也应该会触发异常。谁能帮忙分析分析。反汇编出来的代码是:
; 199 : p = (uint16_t)ata->ata_io_base + 2;
000e7 66 8b 37 mov si, WORD PTR [edi]
; 200 : addr = (byte_t *)(&aa.aa_low);
; 201 : outb(p++,(byte_t)(0xFF & (byte_t)sn));
000ea 8b 4d 18 mov ecx, DWORD PTR _sn$[ebp]
000ed 66 83 c6 02 add si, 2
000f1 51 push ecx
000f2 8b c6 mov eax, esi
000f4 25 ff ff 00 00 and eax, 65535 ; 0000ffffH
000f9 46 inc esi
000fa 50 push eax
000fb e8 00 00 00 00 call _I386_outb
; 202 : outb(p++,*addr++);
00100 8b c6 mov eax, esi
00102 53 push ebx
00103 25 ff ff 00 00 and eax, 65535 ; 0000ffffH
00108 46 inc esi
00109 50 push eax
0010a e8 00 00 00 00 call _I386_outb
; 203 : outb(p++,*addr++);
0010f 8b 55 f5 mov edx, DWORD PTR _aa$[ebp+1]
00112 8b c6 mov eax, esi
00114 25 ff ff 00 00 and eax, 65535 ; 0000ffffH
00119 52 push edx
0011a 50 push eax
0011b 46 inc esi
0011c e8 00 00 00 00 call _I386_outb
; 204 : outb(p++,*addr++);
00121 8b 4d f6 mov ecx, DWORD PTR _aa$[ebp+2]
00124 8b c6 mov eax, esi
00126 25 ff ff 00 00 and eax, 65535 ; 0000ffffH
0012b 51 push ecx
0012c 50 push eax
0012d 46 inc esi
0012e e8 00 00 00 00 call _I386_outb
; 205 : outb(p++,*addr);
00133 8b 55 f7 mov edx, DWORD PTR _aa$[ebp+3]
00136 8b c6 mov eax, esi
00138 25 ff ff 00 00 and eax, 65535 ; 0000ffffH
0013d 46 inc esi
0013e 52 push edx
0013f 50 push eax
00140 89 75 18 mov DWORD PTR _p$[ebp], esi
00143 e8 00 00 00 00 call _I386_outb
; 206 : kprintf("send ata command.port:%04X cmd:%02X ",p,cmd);
00148 8b 45 0c mov eax, DWORD PTR _cmd$[ebp]
0014b 81 e6 ff ff 00
00 and esi, 65535 ; 0000ffffH
00151 25 ff 00 00 00 and eax, 255 ; 000000ffH
00156 50 push eax
00157 56 push esi
00158 68 00 00 00 00 push OFFSET FLAT:??_C@_0CF@DCIB@send?5ata?5command?4port?3?$CF04X?5cmd?3?$CF@ ; `string'
0015d e8 00 00 00 00 call _kprintf
; 207 : //outb(p, cmd);
; 208 : __asm{
; 209 : mov dx,p
00162 66 8b 55 18 mov dx, WORD PTR _p$[ebp]
; 210 : mov al,cmd
00166 8a 45 0c mov al, BYTE PTR _cmd$[ebp]
; 211 : out dx,al
00169 ee out dx, al
; 212 : }
; 213 :
; 214 : kprintf("OK!\n");
0016a 68 00 00 00 00 push OFFSET FLAT:??_C@_04KFOB@OK?$CB?6?$AA@ ; `string'
0016f e8 00 00 00 00 call _kprintf
00174 83 c4 38 add esp, 56 ; 00000038H