研究实验一:
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
回到了主程序内
研究实验三:
1·
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]++;
}
}
研究实验四:
1·
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
- [kanwangxue] 感觉楼主很乖的。有点孩子气。呵呵。 01/27 08:58
- [kanwangxue] it界,进去干嘛啊,到时候自己牛比了,首先写一个自己的语言,自己用。进入IT界不就是随波做流吗/?他 01/27 08:57
- [kanwangxue] 哥们,不要为了赚钱而学计算机。 计算机是年轻时候干的, 30岁后可以开始想赚钱,年轻嘛,不要这么悲 01/27 08:50
- [游客] 怎么说? 01/26 16:22
- [游客] 你这不行啊,差远了! 01/10 22:29
- [chinatree] 谢谢你。相信你也会成功的。 01/09 14:22
- [landyking] 哥们儿,好久不见。相信你会成功的。 12/02 23:34
- [chinatree] 哇哇,被挖坟了。莫生气,只是感觉谦虚些好,就算你的程序真的是史上最强的,也别说出来嘛,自己偷着乐就行 11/20 00:41
- [xiaoyao2012] 你的程序和我的程序比较也不见得你的程序又节约空间,在某种意义上说你的程序用了没学的指令,所以不见得你 11/19 15:39
- [heliang6291] 一起加油啊 07/02 02:45
- [游客] 急需一个汇编程序大作业。。。。。。。。。。。。。。。。。。。??? 12/28 16:50
- [游客] 这么多人喜欢你,我嫉妒了。但你不可以喜欢那么多,允许你在我不需要你的时候帮别人。如果我需要立叫立到。 11/13 13:11
- [tily] 兄弟 我来看你啦 呵呵 最近可好呀 09/26 22:17
- [stqcw] 能加我qq吗?1270911891 我在做课程设计2的时候 遇到点问题 09/24 09:16
- [stqcw] 能加我qq吗?1270911891 我的环境还是有点问题。按下A的时候不能显示满屏的A 09/20 09:36
- [stqcw] 牛人 我在xp里面运行王爽 汇编第二版 p280的例子 按下esc键没反应 呀 怎样在虚拟机里配置一 09/17 15:18
- [landyking] 呵呵,交个朋友,共同学习. 09/08 00:03
- [luyingdzx] 能知道你的QQ吗?或者请加一下我的QQ271190440,可以吗 虽然在论坛能获得解答,但是有的问 08/07 21:32