关于io指令的问题

    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


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值