汇编网首页登录博客注册
chinatree的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
友情链接

[2011-09-20 12:38] 综合研究

研究实验一:
main(){printf("hello,world!");}
编译成功
连接时提示缺少c0s.obj,fp87.lib(这个以前怎么没提示过?),maths.lib,graphics.lib,cs.lib


研究实验二:
1·将下面程序编译,连接,生成exe文件
main()
{
_AX=1;
_BX=1;
_CX=2;
_AX=_BX+_CX;
_AH=_BL+_CL;
_AL=_BH+_CH;
}

2·用debug加载它,用u命令查看编译后的机器码和汇编代码;思考思考main函数在什么段中,用debug怎么样找到其中main函数的代码?
main函数在代码段中,我用的是笨办法,遇到call就跟进,遇到int就步过,直到
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0206   NV UP EI PL ZR NA PE NC
13CD:0206 8BC3          MOV     AX,BX
-p

AX=0001  BX=0001  CX=0002  DX=D8E9  SP=FFE2  BP=FFE2  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0208   NV UP EI PL ZR NA PE NC
13CD:0208 03C1          ADD     AX,CX
-u 1fd
13CD:01FD B80100        MOV     AX,0001
13CD:0200 BB0100        MOV     BX,0001
13CD:0203 B90200        MOV     CX,0002
13CD:0206 8BC3          MOV     AX,BX
13CD:0208 03C1          ADD     AX,CX
13CD:020A 8AE3          MOV     AH,BL
13CD:020C 02E1          ADD     AH,CL
13CD:020E 8AC7          MOV     AL,BH
13CD:0210 02C5          ADD     AL,CH
13CD:0212 5D            POP     BP
13CD:0213 C3            RET
13CD:0214 C3            RET
13CD:0215 55            PUSH    BP
13CD:0216 8BEC          MOV     BP,SP
13CD:0218 EB0A          JMP     0224
13CD:021A 8B1E9E01      MOV     BX,[019E]
-
终于找到了

3·用下面方法打印出程序被加载进行时main函数在代码段中的偏移地址:
main()
{
printf("%X\n",main);
}
思考为什么这个程序能够打印出main函数在代码段中的偏移地址?
我想main在编译时被当做一个标号,标号代表的本就是偏移地址,所以被打印出来了。

4·用debug加载它,仔细找到它中每条c语句对应的汇编代码。
C:\DOCUME~1\ADMINI~1>debug c:\tc\a.exe
-g 1fa

AX=0000  BX=05B2  CX=0015  DX=FCA0  SP=FFE4  BP=FFEE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=01FA   NV UP EI PL ZR NA PE NC
13CD:01FA 55            PUSH    BP
-u
13CD:01FA 55            PUSH    BP;   main(){
13CD:01FB 8BEC          MOV     BP,SP
13CD:01FD B80100        MOV     AX,0001  ;_AX=1;
13CD:0200 BB0100        MOV     BX,0001  ;_BX=1;
13CD:0203 B90200        MOV     CX,0002  ;_CX=2;
13CD:0206 8BC3          MOV     AX,BX   
13CD:0208 03C1          ADD     AX,CX   ;_AX=_BX+_CX;
13CD:020A 8AE3          MOV     AH,BL
13CD:020C 02E1          ADD     AH,CL   ;_AH=_BL+_CL;
13CD:020E 8AC7          MOV     AL,BH
13CD:0210 02C5          ADD     AL,CH   ;_AL=_BH+_CH;
13CD:0212 5D            POP     BP
13CD:0213 C3            RET        ;     }
13CD:0214 C3            RET
13CD:0215 55            PUSH    BP
13CD:0216 8BEC          MOV     BP,SP
13CD:0218 EB0A          JMP     0224
-

5·通过main函数后面有ret指令,我们可设想,c语言将函数实现为汇编语言中的子程序。研究下面程序的汇编代码,验证我们的设想。
void f(void);
main()
{
_AX=1;_BX=1;_CX=2;
f();
}
void f(void)
{
_AX=_BX+_CX;
}



AX=0000  BX=05B2  CX=0016  DX=58D7  SP=FFE6  BP=FFEE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=011A   NV UP EI PL ZR NA PE NC
13CD:011A E8DD00        CALL    01FA
-G 1FA

AX=0000  BX=05B2  CX=0016  DX=2157  SP=FFE4  BP=FFEE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=01FA   NV UP EI PL ZR NA PE NC
13CD:01FA 55            PUSH    BP
-u
13CD:01FA 55            PUSH    BP
13CD:01FB 8BEC          MOV     BP,SP
13CD:01FD B80100        MOV     AX,0001
13CD:0200 BB0100        MOV     BX,0001
13CD:0203 B90200        MOV     CX,0002
13CD:0206 E80200        CALL    020B
13CD:0209 5D            POP     BP
13CD:020A C3            RET
13CD:020B 55            PUSH    BP
13CD:020C 8BEC          MOV     BP,SP
13CD:020E 8BC3          MOV     AX,BX
13CD:0210 03C1          ADD     AX,CX
13CD:0212 5D            POP     BP
13CD:0213 C3            RET
13CD:0214 C3            RET
13CD:0215 55            PUSH    BP
13CD:0216 8BEC          MOV     BP,SP
13CD:0218 EB0A          JMP     0224
-


AX=0001  BX=0001  CX=0002  DX=2157  SP=FFDE  BP=FFDE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0210   NV UP EI PL ZR NA PE NC
13CD:0210 03C1          ADD     AX,CX
-t

AX=0003  BX=0001  CX=0002  DX=2157  SP=FFDE  BP=FFDE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0212   NV UP EI PL NZ NA PE NC
13CD:0212 5D            POP     BP
-t

AX=0003  BX=0001  CX=0002  DX=2157  SP=FFE0  BP=FFE2  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0213   NV UP EI PL NZ NA PE NC
13CD:0213 C3            RET
-t

AX=0003  BX=0001  CX=0002  DX=2157  SP=FFE2  BP=FFE2  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0209   NV UP EI PL NZ NA PE NC
13CD:0209 5D            POP     BP
-t

AX=0003  BX=0001  CX=0002  DX=2157  SP=FFE4  BP=FFEE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=020A   NV UP EI PL NZ NA PE NC
13CD:020A C3            RET

AX=0003  BX=0001  CX=0002  DX=4241  SP=FFE6  BP=FFEE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=011D   NV UP EI PL NZ NA PE NC
13CD:011D 50            PUSH    AX

回到了主程序内

研究实验三:


main(){             /*push bp   mov bp,sp*/
*(char *)0x2000='a';/* mov byte ptr [2000h],61h*/
*(int *)0x2000=0xf;  /*mov word ptr [2000h],0fh*/
*(char far *)0x20001000='a';/*mov bx,2000h   mov es,bx  mov bx,1000h  mov byte ptr es[bx],61h
_AX=0x2000;/*mov ax,2000h*/
*(char *)_AX='b';/*mov bx,ax  mov byte ptr [bx],62h*/
_BX=0x1000;   /*mov bx,1000h*/
*(char *)(_BX+_BX)='a';  /*add bx,bx    mov byte ptr [bx],61h*/
*(char far *)(0x20001000+_BX)=*(char *)_AX; /*mov bx,ax   mov al,[bx]   xor cx,cx  add bx,1000h   adc cx,2000h  mov es,cx  mov es:[bx],al*//*感觉这句效率好差*/
}/*pop bp    ret*/
对main函数单步跟踪,查看相关内存单元的内容。

d 2000:3000
2000:3000  61 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   a...............
2000:3010  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
2000:3020  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
2000:3030  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................


2·用一条语句实现在屏幕中间显示一个绿色的“a”。
main(){*(int far *)0xb8720000=0x261;}

3·c语言将全局变量放在哪?将局部变量放在哪?每个函数开头的“ push bp   mov bp,sp”有什么含义?

int a1,a2,a3;
void f(void);
main(){
int b1,b2,b3;
a1=0xa1;a2=0xa2;a3=0xa3;
b1=0xb1;b2=0xb2;b3=0xb3;
}
void f(void)
{
int c1,c2,c3;
a1=0xfa1;a2=0xfa2;a3=0xfa3;
c1=0xc1;c2=0xc2;c3=0xc3;
}



AX=0000  BX=05B8  CX=0017  DX=F720  SP=FFE4  BP=FFEE  SI=0380  DI=0575
DS=1427  ES=1427  SS=1427  CS=13CD  IP=01FA   NV UP EI PL ZR NA PE NC
13CD:01FA C8            DB      C8
-u
13CD:01FA C8            DB      C8;这里好像反汇编错了
13CD:01FB 06            PUSH    ES
13CD:01FC 0000          ADD     [BX+SI],AL
13CD:01FE C706A601A100  MOV     WORD PTR [01A6],00A1
13CD:0204 C706A801A200  MOV     WORD PTR [01A8],00A2
13CD:020A C706AA01A300  MOV     WORD PTR [01AA],00A3
13CD:0210 C746FAB100    MOV     WORD PTR [BP-06],00B1
13CD:0215 C746FCB200    MOV     WORD PTR [BP-04],00B2
-u
13CD:021A C746FEB300    MOV     WORD PTR [BP-02],00B3
13CD:021F C9            DB      C9
13CD:0220 C3            RET
13CD:0221 C8            DB      C8
13CD:0222 06            PUSH    ES
13CD:0223 0000          ADD     [BX+SI],AL
13CD:0225 C706A601A10F  MOV     WORD PTR [01A6],0FA1
13CD:022B C706A801A20F  MOV     WORD PTR [01A8],0FA2
13CD:0231 C706AA01A30F  MOV     WORD PTR [01AA],0FA3
13CD:0237 C746FAC100    MOV     WORD PTR [BP-06],00C1
-
全局变量是放在数据段的,局部变量是放在栈中,“push bp  mov bp,sp”是用来在栈中寻址操作局部变量的。


4·c语言是把返回值放在哪里?

AX=0000  BX=05B8  CX=0000  DX=20AF  SP=FFDC  BP=FFDC  SI=0380  DI=0575
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0209   NV UP EI PL ZR NA PE NC
13CD:0209 A1A601        MOV     AX,[01A6]                          DS:01A6=0000
-t

AX=0000  BX=05B8  CX=0000  DX=20AF  SP=FFDC  BP=FFDC  SI=0380  DI=0575
DS=1424  ES=1424  SS=1424  CS=13CD  IP=020C   NV UP EI PL ZR NA PE NC
13CD:020C 0306A801      ADD     AX,[01A8]                          DS:01A8=0000
-t

AX=0000  BX=05B8  CX=0000  DX=20AF  SP=FFDC  BP=FFDC  SI=0380  DI=0575
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0210   NV UP EI PL ZR NA PE NC
13CD:0210 A3AA01        MOV     [01AA],AX                          DS:01AA=0000
-t

AX=0000  BX=05B8  CX=0000  DX=20AF  SP=FFDC  BP=FFDC  SI=0380  DI=0575
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0213   NV UP EI PL ZR NA PE NC
13CD:0213 A1AA01        MOV     AX,[01AA]                          DS:01AA=0000
-t

AX=0000  BX=05B8  CX=0000  DX=20AF  SP=FFDC  BP=FFDC  SI=0380  DI=0575
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0216   NV UP EI PL ZR NA PE NC
13CD:0216 EB00          JMP     0218
-

返回值在ax中。

5·下面的程序向安全的地址空间写入“a”到“h”的8个字符:
#define buffer ((char *)*(int far *)0x02000000)
main(){
buffer=(char *)malloc(20);
buffer[10]=0;
while(buffer[10]!=8)
{
buffer[buffer[10]]='a'+buffer[10];
buffer[10]++;
}
}


研究实验四:

f(){
*(char far *)(0xb8000000+160*10+80)='a';
*(char far *)(0xb8000000+160*10+81)=2;
}

编译和连接那个环节会出问题?   连接。
显示的出错信息是什么?         Undefined symbol '_main' in module c0s.
这个错误信息可能与拿个文件相关?  c0s.obj

2·用link.exe对 f.obj进行连接:
f.exe代码有多少字节?        29字节。
程序能正确返货吗?          不能。
f函数的偏移地址是多少?      0.


3·写意个m.c:
main(){
*(char far *)(0xb8000000+160*10+80)='a';
*(char far *)(0xb8000000+160*10+81)=2;
}
编译连接,用debug查看:
m.exe的程序代码总共有多少字节?   342字节。
能正确返回吗?                    能
main函数和f函数的汇编代码有什么不同吗? 没有。

4·对m.exe跟踪,找到调用main的指令地址;找到整个程序的返回指令:


AX=0000  BX=05B2  CX=0000  DX=CB5A  SP=FFEC  BP=FFEE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=010E   NV UP EI PL ZR NA PE NC
13CD:010E FF368800      PUSH    [0088]                             DS:0088=0578
-p

AX=0000  BX=05B2  CX=0000  DX=CB5A  SP=FaEA  BP=FFEE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0112   NV UP EI PL ZR NA PE NC
13CD:0112 FF368600      PUSH    [0086]                             DS:0086=FFEC
-p

AX=0000  BX=05B2  CX=0000  DX=CB5A  SP=FFE8  BP=FFEE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=0116   NV UP EI PL ZR NA PE NC
13CD:0116 FF368400      PUSH    [0084]                             DS:0084=0001
-p

AX=0000  BX=05B2  CX=0000  DX=CB5A  SP=FFE6  BP=FFEE  SI=0380  DI=056F
DS=1424  ES=1424  SS=1424  CS=13CD  IP=011A   NV UP EI PL ZR NA PE NC
13CD:011A E8DD00        CALL    01FA
-p

也是用21h中断4ch功能退出的
13CD:0143 740A          JZ      014F
-p

AX=0000  BX=0691  CX=0000  DX=0740  SP=FFDC  BP=FFE0  SI=002F  DI=056F
DS=1424  ES=B800  SS=1424  CS=13CD  IP=014F   NV UP EI PL ZR NA PE NC
13CD:014F 8BEC          MOV     BP,SP
-p

AX=0000  BX=0691  CX=0000  DX=0740  SP=FFDC  BP=FFDC  SI=002F  DI=056F
DS=1424  ES=B800  SS=1424  CS=13CD  IP=0151   NV UP EI PL ZR NA PE NC
13CD:0151 B44C          MOV     AH,4C
-p

AX=4C00  BX=0691  CX=0000  DX=0740  SP=FFDC  BP=FFDC  SI=002F  DI=056F
DS=1424  ES=B800  SS=1424  CS=13CD  IP=0153   NV UP EI PL ZR NA PE NC
13CD:0153 8A4602        MOV     AL,[BP+02]                         SS:FFDE=00
-p

AX=4C00  BX=0691  CX=0000  DX=0740  SP=FFDC  BP=FFDC  SI=002F  DI=056F
DS=1424  ES=B800  SS=1424  CS=13CD  IP=0156   NV UP EI PL ZR NA PE NC
13CD:0156 CD21          INT     21
-p

Program terminated normally
-p..


5·思考:
1)对main函数调用的指令和程序返回的指令是哪里来的?   c0s.obj吧,我想应该是从这里得到的。
2)是不是tc.exe把c0s.obj和用户程序的.obj文件一起连接生成.exe文件?    是的。
3)对用户程序的main函数进行调用和返回指令是否来自c0s.obj?        是的。
4)我们如何看到c0s.obj文件中的程序代码呢?                  用link.exe将它连接成.exe再用debug加载。
5)c0s.obj文件里有我们设想的代码吗?                      有。
6)用link.exe将c0s.obj连接成c0s.exe,查看c0s.exe和m.exe的汇编代码,有何相同之处?前243字节完全一样,然后从第270字节往后也是相同的,不同地方如下
c0s.obj{call [0194h]  call 00fbh   call 00feh}                               {call [0198h]}  
                             }mov ah,00   int 1ah  mov [98h],dx  mov [9ah],cx
m.exe {call [1a0h]  call 024dh  call 0338}                                   {call [01a4h]}
7)用debug将m.exe和c0s.exe分别加载,找到对main函数进行调用的偏移地址,向后查看10条指令进行对比:
c0s.obj{call [0194h]  call 00fbh   call 00feh}                               {call [0198h]}  
                             }mov ah,00   int 1ah  mov [98h],dx  mov [9ah],cx
m.exe {call [1a0h]  call 024dh  call 0338}                                   {call [01a4h]}
8)重新写个c0s.asm,连接成c0s.obj,替换tc中的c0s.obj。
9)对f.obj进行连接生成f.exe,这次能成功吗?能正确运行吗?    能成功,能运行。
10)将下面程序编译连接,理解f.c  
#define buffer ((char *)*(int far *)0x02000000)
f(){
buffer=(char *)malloc(20);
buffer[10]=0;
while(buffer[10]!=8)
{
buffer[buffer[10]]='a'+buffer[10];
buffer[10]++;
}
}

AX=13CD  BX=0000  CX=028C  DX=0000  SP=0080  BP=0000  SI=0000  DI=0000
DS=13CD  ES=13BD  SS=13CD  CS=13D5  IP=000A   NV UP EI PL NZ NA PO NC
13D5:000A E80500        CALL    0012
-t

AX=13CD  BX=0000  CX=028C  DX=0000  SP=007E  BP=0000  SI=0000  DI=0000
DS=13CD  ES=13BD  SS=13CD  CS=13D5  IP=0012   NV UP EI PL NZ NA PO NC
13D5:0012 55            PUSH    BP
-u
13D5:0012 55            PUSH    BP;   f(){
13D5:0013 8BEC          MOV     BP,SP
13D5:0015 BB0002        MOV     BX,0200  ;(char *)*(int far *)0x02000000
13D5:0018 8EC3          MOV     ES,BX
13D5:001A 33DB          XOR     BX,BX    
13D5:001C 26            ES:
13D5:001D C7070000      MOV     WORD PTR [BX],0000 ; Buffer=0
13D5:0021 BB0002        MOV     BX,0200
13D5:0024 8EC3          MOV     ES,BX
13D5:0026 33DB          XOR     BX,BX
13D5:0028 26            ES:
13D5:0029 8B1F          MOV     BX,[BX]        
13D5:002B C6470A00      MOV     BYTE PTR [BX+0A],00   Buffer[10]=0
13D5:002F EB3C          JMP     006D
13D5:0031 BB0002        MOV     BX,0200
13D5:0034 8EC3          MOV     ES,BX
13D5:0036 33DB          XOR     BX,BX
13D5:0038 26            ES:
13D5:0039 8B1F          MOV     BX,[BX]
13D5:003B 8A470A        MOV     AL,[BX+0A]
13D5:003E 0461          ADD     AL,61      ;'a'+Buffer[10]
13D5:0040 BB0002        MOV     BX,0200
13D5:0043 8EC3          MOV     ES,BX
13D5:0045 33DB          XOR     BX,BX
13D5:0047 26            ES:
13D5:0048 8B1F          MOV     BX,[BX]
13D5:004A 50            PUSH    AX
13D5:0043 8EC3          MOV     ES,BX
13D5:0045 33DB          XOR     BX,BX
13D5:0047 26            ES:
13D5:0048 8B1F          MOV     BX,[BX]
13D5:004A 50            PUSH    AX
-u
13D5:004B 53            PUSH    BX
13D5:004C BB0002        MOV     BX,0200
13D5:004F 8EC3          MOV     ES,BX
13D5:0051 33DB          XOR     BX,BX
13D5:0053 26            ES:
13D5:0054 8B1F          MOV     BX,[BX]
13D5:0056 8A470A        MOV     AL,[BX+0A]
13D5:0059 98            CBW
13D5:005A 5B            POP     BX
13D5:005B 03D8          ADD     BX,AX  ; [Buffer[10]]
13D5:005D 58            POP     AX
13D5:005E 8807          MOV     [BX],AL  ;Buffer[Buffer[10]]=al
13D5:0060 BB0002        MOV     BX,0200
13D5:0063 8EC3          MOV     ES,BX
13D5:0065 33DB          XOR     BX,BX
13D5:0067 26            ES:
13D5:0068 8B1F          MOV     BX,[BX]
13D5:006A FE470A        INC     BYTE PTR [BX+0A]  ;Buffer[10]++
13D5:006D BB0002        MOV     BX,0200            
13D5:0070 8EC3          MOV     ES,BX
13D5:0072 33DB          XOR     BX,BX
13D5:0074 26            ES:
13D5:0075 8B1F          MOV     BX,[BX]
13D5:0077 807F0A08      CMP     BYTE PTR [BX+0A],08  ;while(Buffer[10]!=8)
13D5:007B 75B4          JNZ     0031
13D5:007D 5D            POP     BP
13D5:007E C3            RET
13D5:007F 00FB          ADD     BL,BH
13D5:0081 52            PUSH    DX
13D5:0082 0802          OR      [BP+SI],AL
13D5:0084 1900          SBB     [BX+SI],AX
13D5:0086 0000          ADD     [BX+SI],AL
13D5:0088 06            PUSH    ES
13D5:0089 0019          ADD     [BX+DI],BL
13D5:008B 0000          ADD     [BX+SI],AL
-

研究实验五:
-g 1fa

AX=0000  BX=083C  CX=0014  DX=8D4E  SP=FFE4  BP=FFEE  SI=0380  DI=07F9
DS=1503  ES=1503  SS=1503  CS=13CD  IP=01FA   NV UP EI PL ZR NA PE NC
13CD:01FA 55            PUSH    BP
-u
13CD:01FA 55            PUSH    BP
13CD:01FB 8BEC          MOV     BP,SP
13CD:01FD B89401        MOV     AX,0194
13CD:0200 50            PUSH    AX;   这里sp=0ffe0h
13CD:0201 E8B708        CALL    0ABB
13CD:0204 59            POP     CX
13CD:0205 5D            POP     BP
13CD:0206 C3            RET
13CD:0207 55            PUSH    BP
13CD:0208 8BEC          MOV     BP,SP
13CD:020A 56            PUSH    SI
13CD:020B 8B7604        MOV     SI,[BP+04]
13CD:020E 0BF6          OR      SI,SI
13CD:0210 7C14          JL      0226
13CD:0212 83FE58        CMP     SI,+58
13CD:0215 7603          JBE     021A
13CD:0217 BE5700        MOV     SI,0057
13CD:0200 50            PUSH    AX
13CD:0201 E8B708        CALL    0ABB
13CD:0204 59            POP     CX
13CD:0205 5D            POP     BP
13CD:0206 C3            RET
13CD:0207 55            PUSH    BP
13CD:0208 8BEC          MOV     BP,SP
13CD:020A 56            PUSH    SI
13CD:020B 8B7604        MOV     SI,[BP+04]
13CD:020E 0BF6          OR      SI,SI
13CD:0210 7C14          JL      0226
13CD:0212 83FE58        CMP     SI,+58
13CD:0215 7603          JBE     021A
13CD:0217 BE5700        MOV     SI,0057
-d ds:0194
1503:0190              68 65 6C 6C-6F 2C 77 6F 72 6C 64 21       hello,world!
1503:01A0  00 00 00 00 00 13 02 02-04 05 06 08 08 08 14 15   ................
1503:01B0  05 13 FF 16 05 11 02 FF-FF FF FF FF FF FF FF FF   ................
1503:01C0  FF FF FF FF 05 05 FF FF-FF FF FF FF FF FF FF FF   ................
1503:01D0  FF FF FF FF FF FF 0F FF-23 02 FF 0F FF FF FF FF   ........#.......
1503:01E0  13 FF FF 02 02 05 0F 02-FF FF FF 13 FF FF FF FF   ................
1503:01F0  FF FF FF FF 23 FF FF FF-FF 23 FF 13 FF 00 42 02   ....#....#....B.
1503:0200  42 02 42 02 00 00 00 10-00 00 00 00 09 02 00 00   B.B.............
1503:0210  00 00 00 00                                       ....

这个ds:194是字符串的首地址,存在ss:0ffe0h

AX=0194  BX=083C  CX=0014  DX=CEB7  SP=FFDE  BP=FFE2  SI=0380  DI=07F9
DS=1503  ES=1503  SS=1503  CS=13CD  IP=0ABB   NV UP EI PL ZR NA PE NC
13CD:0ABB 55            PUSH    BP
-u
13CD:0ABB 55            PUSH    BP
13CD:0ABC 8BEC          MOV     BP,SP;     这里bp=0ffdch
13CD:0ABE B8330C        MOV     AX,0C33
13CD:0AC1 50            PUSH    AX
13CD:0AC2 B81A02        MOV     AX,021A
13CD:0AC5 50            PUSH    AX
13CD:0AC6 FF7604        PUSH    [BP+04];   [bp+4]->ffe0h,就是存0194那个地址的位置
13CD:0AC9 8D4606        LEA     AX,[BP+06]; 这是调用这个子程序时的bp位置
13CD:0ACC 50            PUSH    AX
13CD:0ACD E84C02        CALL    0D1C;再跟进去就是printf的具体实现代码了
13CD:0AD0 EB00          JMP     0AD2
13CD:0AD2 5D            POP     BP
13CD:0AD3 C3            RET
13CD:0AD4 55            PUSH    BP
13CD:0AD5 8BEC          MOV     BP,SP
13CD:0AD7 8B5E06        MOV     BX,[BP+06]
13CD:0ADA FF0F          DEC     WORD PTR [BX]
-

DS=1503  ES=1503  SS=1503  CS=13CD  IP=0ACD   NV UP EI PL ZR NA PE NC
13CD:0ACD E84C02        CALL    0D1C
-t

AX=FFE2  BX=083C  CX=0015  DX=066C  SP=FFD2  BP=FFDC  SI=0380  DI=07F9
DS=1503  ES=1503  SS=1503  CS=13CD  IP=0D1C   NV UP EI PL ZR NA PE NC
13CD:0D1C 55            PUSH    BP
-u
13CD:0D1C 55            PUSH    BP
13CD:0D1D 8BEC          MOV     BP,SP
13CD:0D1F 81EC9600      SUB     SP,0096
13CD:0D23 56            PUSH    SI
13CD:0D24 57            PUSH    DI
13CD:0D25 C746AA0000    MOV     WORD PTR [BP-56],0000
13CD:0D2A C646AD50      MOV     BYTE PTR [BP-53],50
13CD:0D2E EB38          JMP     0D68
13CD:0D30 57            PUSH    DI
13CD:0D31 B9FFFF        MOV     CX,FFFF
13CD:0D34 32C0          XOR     AL,AL
13CD:0D36 F2            REPNZ
13CD:0D37 AE            SCASB
13CD:0D38 F7D1          NOT     CX
13CD:0D3A 49            DEC     CX
13CD:0D3B 5F            POP     DI
-
没有看到是以什么做为结束标志的,猜测是以0为结束,我做了一个实验:

13CD:0201 E8BF08        CALL    0AC3
13CD:0204 59            POP     CX
13CD:0205 B8A201        MOV     AX,01A2
13CD:0208 50            PUSH    AX
13CD:0209 E8B708        CALL    0AC3
13CD:020C 59            POP     CX
13CD:020D 5D            POP     BP
13CD:020E C3            RET
13CD:020F 55            PUSH    BP
13CD:0210 8BEC          MOV     BP,SP
13CD:0212 56            PUSH    SI
13CD:0213 8B7604        MOV     SI,[BP+04]
13CD:0216 0BF6          OR      SI,SI
13CD:0218 7C14          JL      022E
-d ds:0194
1504:0190              68 65 6C 6C-6F 2C 77 6F 72 6C 64 21       hello,world!
1504:01A0  0A 00 61 62 63 64 00 00-00 00 00 13 02 02 04 05   ..abcd..........
1504:01B0  06 08 08 08 14 15 05 13-FF 16 05 11 02 FF FF FF   ................
1504:01C0  FF FF FF FF FF FF FF FF-FF FF 05 05 FF FF FF FF   ................
1504:01D0  FF FF FF FF FF FF FF FF-FF FF FF FF 0F FF 23 02   ..............#.
1504:01E0  FF 0F FF FF FF FF 13 FF-FF 02 02 05 0F 02 FF FF   ................
1504:01F0  FF 13 FF FF FF FF FF FF-FF FF 23 FF FF FF FF 23   ..........#....#
1504:0200  FF 13 FF 00 4A 02 4A 02-4A 02 00 00 00 10 00 00   ....J.J.J.......
1504:0210  00 00 09 02                                       ....
-

发现在ds:01a1的位置是0然后是下一句的开始,证明了我猜测

1·  showchar()是通过栈来传递的


void showchar(char a,int b);
main()
{
showchar('a',2);
}
void showchar(char a,int b)
{
*(char far *)(0xb8000000+106*10+80)=a;
*(char far *)(0xb8000000+106*10+81)=b;
}
13CD:0209 8BEC          MOV     BP,SP
13CD:020B 8A4604        MOV     AL,[BP+04]
13CD:020E BB00B8        MOV     BX,B800
13CD:0211 8EC3          MOV     ES,BX
13CD:0213 BB7404        MOV     BX,0474
13CD:0216 26            ES:
13CD:0217 8807          MOV     [BX],AL
13CD:0219 8A4606        MOV     AL,[BP+06]
-u 208
13CD:0208 55            PUSH    BP
13CD:0209 8BEC          MOV     BP,SP
13CD:020B 8A4604        MOV     AL,[BP+04]<-'a'
13CD:020E BB00B8        MOV     BX,B800
13CD:0211 8EC3          MOV     ES,BX
13CD:0213 BB7404        MOV     BX,0474
13CD:0216 26            ES:
13CD:0217 8807          MOV     [BX],AL
13CD:0219 8A4606        MOV     AL,[BP+06] <-'2' 
13CD:021C BB00B8        MOV     BX,B800
13CD:021F 8EC3          MOV     ES,BX
13CD:0221 BB7504        MOV     BX,0475
13CD:0224 26            ES:
13CD:0225 8807          MOV     [BX],AL
13CD:0227 5D            POP     BP

-d ss:ffd0 ffff
1425:FFD0  37 04 48 00 00 00 E2 FF-01 02 CD 13 D6 0D 61 00   7.H...........a.
1425:FFE0  02 00 EE FF 1D 01 01 00-EC FF 78 05 F0 FF 00 00   ..........x.....
1425:FFF0  43 3A 5C 54 43 5C 41 2E-45 58 45 00 F8 00 FB 00   C:\TC\A.EXE.....
-
-貌似在1425:ffde处进行数据对齐了,因为8086栈只能ji9nxing字操作
13CD:0219 8A4606        MOV     AL,[BP+06] <-'2' 但是在这为什么是字节呢?这里不是用int定义的吗?


2·也是通过栈传递参数的
13CD:01FB 8BEC          MOV     BP,SP
13CD:01FD 6A            DB      6A  
13CD:01FE 68            DB      68  ;push 68
13CD:01FF 6A            DB      6A
13CD:0200 67            DB      67  ;push 67
13CD:0201 6A            DB      6A
13CD:0202 66            DB      66  ;push 66
13CD:0203 6A            DB      6A
13CD:0204 65            DB      65  ;push 65
13CD:0205 6A            DB      6A
13CD:0206 64            DB      64  ;push 64
13CD:0207 6A            DB      6A
13CD:0208 63            DB      63  ;push 63
13CD:0209 6A            DB      6A
13CD:020A 62            DB      62  ;push 62
13CD:020B 6A            DB      6A
13CD:020C 61            DB      61  ;push 61
13CD:020D 6A            DB      6A
13CD:020E 026A08        ADD     CH,[BP+SI+08];这里是push 02  push 08这里貌似把参数的数量也亚进去了
13CD:0211 E80500        CALL    0219
13CD:0214 83C414        ADD     SP,+14
13CD:0217 5D            POP     BP
13CD:0218 C3            RET
13CD:0219 55            PUSH    BP
-
AX=0000  BX=05B2  CX=0017  DX=99F1  SP=FFC8  BP=FFCA  SI=0000  DI=056F
DS=142A  ES=142A  SS=142A  CS=13CD  IP=021F   NV UP EI PL ZR NA PE NC
13CD:021F EB47          JMP     0268
-t

AX=0000  BX=05B2  CX=0017  DX=99F1  SP=FFC8  BP=FFCA  SI=0000  DI=056F
DS=142A  ES=142A  SS=142A  CS=13CD  IP=0268   NV UP EI PL ZR NA PE NC
13CD:0268 3B7604        CMP     SI,[BP+04]                         SS:FFCE=0008
-u
13CD:0268 3B7604        CMP     SI,[BP+04]
13CD:026B 75B4          JNZ     0221
13CD:026D 5E            POP     SI
13CD:026E 5D            POP     BP
13CD:026F C3            RET
13CD:0270 C3            RET
13CD:0271 55            PUSH    BP
13CD:0272 8BEC          MOV     BP,SP
13CD:0274 EB0A          JMP     0280
13CD:0276 8B1E9E01      MOV     BX,[019E]
13CD:027A D1E3          SHL     BX,1
13CD:027C FF97A601      CALL    [BX+01A6]
13CD:0280 A19E01        MOV     AX,[019E]
13CD:0283 FF0E9E01      DEC     WORD PTR [019E]
13CD:0287 0BC0          OR      AX,AX
-
-d ss:ffca
142A:FFC0                                E2 FF 14 02 (08 00)   <-bp+4
142A:FFD0  02 00 61 00 62 00 63 00-64 00 65 00 66 00 67 00   
142A:FFE0  68 00 EE FF 1D 01 01 00-EC FF 78 05 F0 FF 00 00   
142A:FFF0  43 3A 5C 54 43 5C 41 2E-45 58 45 00 F8 00 FB 00   
-
又看了一下源码,发现已经把参数的数量告诉函数了
void showchar(int,int,...);
main()
{
showchar(8,2,'a','b','c','d','e','f','g','h');《——这里8对应的是n
}
void showchar(int n,int color,...)
{
int a;
for(a=0;a!=n;a++)
{
*(char far *)(0xb8000000+106*10+80+a+a)=*(int *)(_BP+8+8+a);
*(char far *)(0xb8000000+106*10+81+a+a)=color;
}
}
3·自己写个printf函数,实现%c和%d输出

print:      ;入口参数: ax=要显示的东西,cl=格式控制字符
push ss
pop ds
cmp cl,"c"
jne s
push bp
mov bp,sp
push bx
mov bx,"$"
push bx
push ax
mov dx,sp
mov ah,9
int 21h
mov sp,bp
pop bp
ret
s:cmp cl,"d"
jnz rt
jmp ee
a dw 0,0,0,0,0,0
b db"$"
ee:push cs
pop ds
push dx
push bx
push bp
mov bp,sp
xor bx,bx
cmp ax,32768
jb qq
neg ax
inc ax
mov bx,"-"
qq:push bx
mov cx,10
xor bx,bx
sss:xor dx,dx
div cx
add dx,30h
push dx
inc bl
cmp ax,0
jnz sss
mov cx,bx
xor bx,bx
y:pop a[bx+2]
add bx,2
loop y
pop a[0]
mov dx,offset a
mov ah,9
int 21h
mov sp,bp
pop bp
pop bx
pop dx
rt:ret
评论次数(1)  |  浏览次数(863)  |  类型(汇编作业) |  收藏此文  | 

[  tomato   发表于  2011-09-21 08:33  ]

做的没问题。实验五是不是还没做完?接下来可以把实验五完成!

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码