leonwxqian 发布的文章

闲来无事build一个checked sys试试

元旦看了两天书,正儿八经做一个驱动吧,可惜一编译就跪了……

C:\drivers\firstddk>build
BUILD: Compile and Link for x86
BUILD: Loading e:\winddk\7600.16385.1\build.dat...
BUILD: Computing Include file dependencies:
BUILD: Start time: Sat Jan 03 14:15:05 2015
BUILD: Examining c:\drivers\firstddk directory for files to compile.
BUILD: Saving e:\winddk\7600.16385.1\build.dat...
BUILD: Compiling and Linking c:\drivers\firstddk directory
Configuring OACR for 'root:x86chk' - <OACR on>
_NT_TARGET_VERSION SET TO WINXP
Compiling - mini_ddk.c
1>errors in directory c:\drivers\firstddk
1>e:\winddk\7600.16385.1\inc\api\sal.h(160) : error C1083: Cannot open include f
ile: 'codeanalysis\sourceannotations.h': No such file or directory
Linking Executable - sys\i386\ddk_helloworld.sys
1>link : error LNK1181: cannot open input file 'c:\drivers\firstddk\objchk_wxp_x
86\i386\mini_ddk.obj'
BUILD: Finish time: Sat Jan 03 14:15:06 2015
BUILD: Done

    3 files compiled - 1 Error
    1 executable built - 1 Error

网上的解法也是屌。简单粗暴(via:http://blog.csdn.net/devday/article/details/6683329
f1.png

好哎,终于摆脱vs就给编出来了
f1.jpg

C:\drivers\firstddk>build
BUILD: Compile and Link for x86
BUILD: Loading e:\winddk\7600.16385.1\build.dat...
BUILD: Computing Include file dependencies:
BUILD: Start time: Sat Jan 03 14:19:46 2015
BUILD: Examining c:\drivers\firstddk directory for files to compile.
BUILD: Saving e:\winddk\7600.16385.1\build.dat...
BUILD: Compiling and Linking c:\drivers\firstddk directory
Configuring OACR for 'root:x86chk' - <OACR on>
_NT_TARGET_VERSION SET TO WINXP
Compiling - mini_ddk.c
Linking Executable - sys\i386\ddk_helloworld.sys
BUILD: Finish time: Sat Jan 03 14:19:48 2015
BUILD: Done

    3 files compiled - 69 LPS
    1 executable built

然后就是蓝屏之路了呗
出师未捷身先死,OACR刚一警告就发生了除以零异常
f1.png

f1.png

f2.png

古人诚不欺我也
f1.png

好就好在终于还是成功了,感动涕零
f1.png

上次这么舒爽的时候,还是小学踢球踢坏别人窗户那会儿呢
f2.png

4ab48f3cgw1enfzcof2olj20cf0b50v8.jpg

c的类型提升的一点小测试

之前似乎是在哪儿有听说过,今天听人正式的说了一下,自己测试了测试,果然如此。

代码如下
f2.png

编译之后,运行结果是4,char明显变成了一个int
f1.png

使用DDD跟踪,发现编译器在生成阶段就已经算好sizeof 'A'的值是4,硬编码进去了……
f3.png

相反,如果之前定义char x = 'a'; 最后输出sizeof x,那这时又变成了1。
f4.png

发生提升的时候一般都是在表达式中,低于int的整形提升到int,低于double的浮点提升到double。 这个东西完全取决于编译器,上面第二个例子也是编译器提前算好的,只不过由于明确定义了这个东西的类型,所以编译器算出来的是1。 实际上char+char的时候是先int+int然后裁剪成一个char,看看编译出来的代码即知。

花样繁多:函数到底能怎么返回值?

eax返回值不假,但是eax 不就4个字节吗,各种代码通过eax返回时到底有多少花样? have a try:

1、 long long
f1.png

Dump of assembler code for function fun():
=> 0x00401500 <+0>: push   %ebp
   0x00401501 <+1>: mov    %esp,%ebp
   0x00401503 <+3>: mov    $0x11223344,%eax
   0x00401508 <+8>: mov    $0x0,%edx
   0x0040150d <+13>:    pop    %ebp
   0x0040150e <+14>:    ret    
End of assembler dump.

Dump of assembler code for function main(int, char**):
   0x0040150f <+0>: push   %ebp
   0x00401510 <+1>: mov    %esp,%ebp
   0x00401512 <+3>: and    $0xfffffff0,%esp
   0x00401515 <+6>: sub    $0x10,%esp
   0x00401518 <+9>: call   0x409650 <__main>
   0x0040151d <+14>:    call   0x401500 <fun()>
   0x00401522 <+19>:    mov    %eax,0x8(%esp)
   0x00401526 <+23>:    mov    %edx,0xc(%esp)
   0x0040152a <+27>:    mov    $0x0,%eax
   0x0040152f <+32>:    leave  
   0x00401530 <+33>:    ret    
End of assembler dump.

edx小伙加入了。

2、 真 long long。

事实上又拉了一个战友过来
f2.png

->->post-prompt
Dump of assembler code for function main(int, char**):
   0x0040150f <+0>: push   %ebp
   0x00401510 <+1>: mov    %esp,%ebp
   0x00401512 <+3>: and    $0xfffffff0,%esp
   0x00401515 <+6>: sub    $0x10,%esp
   0x00401518 <+9>: call   0x409650 <__main>
=> 0x0040151d <+14>:    call   0x401500 <fun()>
   0x00401522 <+19>:    mov    %eax,0x8(%esp)
   0x00401526 <+23>:    mov    %edx,0xc(%esp)  <==注意这里
   0x0040152a <+27>:    mov    $0x0,%eax
   0x0040152f <+32>:    leave  
   0x00401530 <+33>:    ret    
End of assembler dump.

->->pre-prompt
(gdb) 
->->prompt

->->post-prompt
Dump of assembler code for function fun():
   0x00401500 <+0>: push   %ebp
   0x00401501 <+1>: mov    %esp,%ebp
   0x00401503 <+3>: mov    $0x11223344,%eax
   0x00401508 <+8>: mov    $0x0,%edx
   0x0040150d <+13>:    pop    %ebp
   0x0040150e <+14>:    ret    
End of assembler dump.

3、 超long long long long
ecx参战的感觉。
f33.png

用Intel的吧,大家也方便看一点

fun():
   0x00401500 <+0>: push   ebp
   0x00401501 <+1>: mov    ebp,esp
   0x00401503 <+3>: sub    esp,0xc
=> 0x00401506 <+6>: mov    eax,0xab33bc40
   0x0040150b <+11>:    mov    edx,0x89119a22
   0x00401510 <+16>:    mov    ecx,0x403b
   0x00401515 <+21>:    mov    DWORD PTR [ebp-0xc],eax
   0x00401518 <+24>:    mov    DWORD PTR [ebp-0x8],edx
   0x0040151b <+27>:    mov    DWORD PTR [ebp-0x4],ecx
   0x0040151e <+30>:    fld    TBYTE PTR [ebp-0xc]
   0x00401521 <+33>:    leave  
   0x00401522 <+34>:    ret    

4、 真· 超long long long long
f4.png

long128构造函数:

   0x00415fb0 <+0>: push   ebp
   0x00415fb1 <+1>: mov    ebp,esp
   0x00415fb3 <+3>: sub    esp,0x18
   0x00415fb6 <+6>: mov    DWORD PTR [ebp-0x4],ecx
   0x00415fb9 <+9>: mov    eax,DWORD PTR [ebp+0x8]
   0x00415fbc <+12>:    mov    DWORD PTR [ebp-0x10],eax
   0x00415fbf <+15>:    mov    eax,DWORD PTR [ebp+0xc]
   0x00415fc2 <+18>:    mov    DWORD PTR [ebp-0xc],eax
   0x00415fc5 <+21>:    mov    eax,DWORD PTR [ebp+0x10]
   0x00415fc8 <+24>:    mov    DWORD PTR [ebp-0x18],eax
   0x00415fcb <+27>:    mov    eax,DWORD PTR [ebp+0x14]
   0x00415fce <+30>:    mov    DWORD PTR [ebp-0x14],eax
   0x00415fd1 <+33>:    mov    ecx,DWORD PTR [ebp-0x4]  <== this
   0x00415fd4 <+36>:    mov    eax,DWORD PTR [ebp-0x10]
   0x00415fd7 <+39>:    mov    edx,DWORD PTR [ebp-0xc]
   0x00415fda <+42>:    mov    DWORD PTR [ecx],eax      <== eax, edx合起来就是一个long long
   0x00415fdc <+44>:    mov    DWORD PTR [ecx+0x4],edx
   0x00415fdf <+47>:    mov    ecx,DWORD PTR [ebp-0x4]
   0x00415fe2 <+50>:    mov    eax,DWORD PTR [ebp-0x18]
   0x00415fe5 <+53>:    mov    edx,DWORD PTR [ebp-0x14]
   0x00415fe8 <+56>:    mov    DWORD PTR [ecx+0x8],eax   <== 同上,另一个赋值操作
   0x00415feb <+59>:    mov    DWORD PTR [ecx+0xc],edx
=> 0x00415fee <+62>:    leave  
   0x00415fef <+63>:    ret    0x10

fun():

   0x00401500 <+0>: push   ebp
   0x00401501 <+1>: mov    ebp,esp
   0x00401503 <+3>: sub    esp,0x10 <==本地的缓冲区
   0x00401506 <+6>: mov    DWORD PTR [esp+0x8],0x44332211
   0x0040150e <+14>:    mov    DWORD PTR [esp+0xc],0x88776655
   0x00401516 <+22>:    mov    DWORD PTR [esp],0x55667788
   0x0040151d <+29>:    mov    DWORD PTR [esp+0x4],0x11223344  <==把这几个倒霉数字存进去
   0x00401525 <+37>:    mov    ecx,DWORD PTR [ebp+0x8] <==ebp+0x8,这个临时的long128变量地址
   0x00401528 <+40>:    call   0x415fb0 <long128::long128(long long, long long)>
   0x0040152d <+45>:    sub    esp,0x10  <==栈上的缓冲区释放掉
=> 0x00401530 <+48>:    mov    eax,DWORD PTR [ebp+0x8]   <==变量的地址返回eax……
   0x00401533 <+51>:    leave  
   0x00401534 <+52>:    ret    

main():

   0x00401535 <+0>: push   ebp
   0x00401536 <+1>: mov    ebp,esp
   0x00401538 <+3>: and    esp,0xfffffff0
   0x0040153b <+6>: sub    esp,0x20
   0x0040153e <+9>: call   0x409680 <__main>
   0x00401543 <+14>:    lea    eax,[esp+0x10] <==long128的内存
   0x00401547 <+18>:    mov    DWORD PTR [esp],eax
   0x0040154a <+21>:    call   0x401500 <fun()> <==别忘了这时候已经赋值给long128 tempA了
=> 0x0040154f <+26>:    mov    eax,0x0  <== return 0;
   0x00401554 <+31>:    leave  
   0x00401555 <+32>:    ret    

call = push + jmp,

esp => [ EAX ]

aftercall:

esp =>  [ retnaddr ]
        [   EAX    ]

1st instruction:

esp =>  [   ebp    ] 
        [ retnaddr ]
        [   EAX    ]  <= esp+8

上一层预留空间了,学会废物利用了。

5、假·超long long long long
f5.png
fun():

   0x00401500 <+0>: push   ebp
   0x00401501 <+1>: mov    ebp,esp
=> 0x00401503 <+3>: mov    eax,DWORD PTR [ebp+0x8] <==long128的地址
   0x00401506 <+6>: mov    DWORD PTR [eax],0x55667788  <==第一次赋值
   0x0040150c <+12>:    mov    DWORD PTR [eax+0x4],0x11223344
   0x00401513 <+19>:    mov    eax,DWORD PTR [ebp+0x8] 
   0x00401516 <+22>:    mov    DWORD PTR [eax+0x8],0x44332211 <==第二次赋值
   0x0040151d <+29>:    mov    DWORD PTR [eax+0xc],0x88776655
   0x00401524 <+36>:    nop
   0x00401525 <+37>:    mov    eax,DWORD PTR [ebp+0x8]
   0x00401528 <+40>:    pop    ebp
   0x00401529 <+41>:    ret    

main():

   0x0040152a <+0>: push   ebp
   0x0040152b <+1>: mov    ebp,esp
   0x0040152d <+3>: and    esp,0xfffffff0
   0x00401530 <+6>: sub    esp,0x20
   0x00401533 <+9>: call   0x409670 <__main>
   0x00401538 <+14>:    lea    eax,[esp+0x10]
   0x0040153c <+18>:    mov    DWORD PTR [esp],eax
   0x0040153f <+21>:    call   0x401500 <fun()>
=> 0x00401544 <+26>:    mov    eax,0x0
   0x00401549 <+31>:    leave  
   0x0040154a <+32>:    ret    

看来跟之前一样。

6、 terminated
多加一句varA.h1++;

   0x0040152a <+0>: push   ebp
   0x0040152b <+1>: mov    ebp,esp
   0x0040152d <+3>: and    esp,0xfffffff0
   0x00401530 <+6>: sub    esp,0x20
   0x00401533 <+9>: call   0x409680 <__main>
=> 0x00401538 <+14>:    lea    eax,[esp+0x10]
   0x0040153c <+18>:    mov    DWORD PTR [esp],eax
   0x0040153f <+21>:    call   0x401500 <fun()>
   0x00401544 <+26>:    mov    eax,DWORD PTR [esp+0x10]
   0x00401548 <+30>:    mov    edx,DWORD PTR [esp+0x14]
   0x0040154c <+34>:    add    eax,0x1
   0x0040154f <+37>:    adc    edx,0x0
   0x00401552 <+40>:    mov    DWORD PTR [esp+0x10],eax
   0x00401556 <+44>:    mov    DWORD PTR [esp+0x14],edx
   0x0040155a <+48>:    mov    eax,0x0
   0x0040155f <+53>:    leave  
   0x00401560 <+54>:    ret    

ok done.有空再研究研究其他的。