void showchar(char a,int b);
main()
{
showchar('a',2);
}
void showchar(char a,int b)
{
*(char far *)(0xb8000000+160*10+80)=a;
*(char far *)(0xb8000000+160*10+81)=b;
}
用tc.exe对a.c进行编译,连接,生成a.exe.用debug加载a.exe,对函数的汇编代码进行分析。解答这两
个问题:main函数是如何给showchar传递参数的?showchar是如何接收参数的?
下面是反汇编后的代码:
140E:01FA 55 PUSH BP
140E:01FB 8BEC MOV BP,SP
140E:01FD B80200 MOV AX,0002
140E:0200 50 PUSH AX
140E:0201 B061 MOV AL,61
140E:0203 50 PUSH AX
140E:0204 E80400 CALL 020B
140E:0207 59 POP CX
140E:0208 59 POP CX
140E:0209 5D POP BP
140E:020A C3 RET
140E:020B 55 PUSH BP
140E:020C 8BEC MOV BP,SP
140E:020E 8A4604 MOV AL,[BP+04]
140E:0211 BB00B8 MOV BX,B800
140E:0214 8EC3 MOV ES,BX
140E:0216 BB9006 MOV BX,0690
140E:0219 26 ES:
140E:021A 8807 MOV [BX],AL
140E:021C 8A4606 MOV AL,[BP+06]
140E:021F BB00B8 MOV BX,B800
140E:0222 8EC3 MOV ES,BX
140E:0224 BB9106 MOV BX,0691
140E:0227 26 ES:
140E:0228 8807 MOV [BX],AL
140E:022A 5D POP BP
140E:022B C3 RET
通过跟踪,发现main函数将要给showchar传递的参数入栈,showchar再从栈中取出main函数压入栈的值!
(2)写一个程序b.c
void showchar(int,int,...);
main()
{
showchar(8,2,'a','b','c','d','e','f','g','h');
}
void showchar(int n,in color,...)
{
int a;
for(a=0;a!=n;a++)
{
*(char far *)(0xb8000000+160*10+80+a+a)=*(int *)(_BP+8+a+a);
*(char far *)(0xb8000000+160*10+81+a+a)=color;
}
}
分析程序b.c,深入理解相关知识。
思考:showchar函数是如何知道要显示多少个字符的?printf函数是如何知道有多少个参数的?
反汇编代码如下:
140E:01FA 55 PUSH BP
140E:01FB 8BEC MOV BP,SP
140E:01FD B86800 MOV AX,0068
140E:0200 50 PUSH AX
140E:0201 B86700 MOV AX,0067
140E:0204 50 PUSH AX
140E:0205 B86600 MOV AX,0066
140E:0208 50 PUSH AX
140E:0209 B86500 MOV AX,0065
140E:020C 50 PUSH AX
140E:020D B86400 MOV AX,0064
140E:0210 50 PUSH AX
140E:0211 B86300 MOV AX,0063
140E:0214 50 PUSH AX
140E:0215 B86200 MOV AX,0062
140E:0218 50 PUSH AX
140E:0219 B86100 MOV AX,0061
140E:021C 50 PUSH AX
140E:021D B80200 MOV AX,0002
140E:0220 50 PUSH AX
140E:0221 B80800 MOV AX,0008
140E:0224 50 PUSH AX
140E:0225 E80500 CALL 022D
140E:0228 83C414 ADD SP,+14
140E:022B 5D POP BP
140E:022C C3 RET
140E:022D 55 PUSH BP
140E:022E 8BEC MOV BP,SP
140E:0230 56 PUSH SI
140E:0231 33F6 XOR SI,SI
140E:0233 EB49 JMP 027E
140E:0235 8BDD MOV BX,BP
140E:0237 03DE ADD BX,SI
140E:0239 03DE ADD BX,SI
140E:023B 83C308 ADD BX,+08
140E:023E 8A07 MOV AL,[BX]
140E:0240 50 PUSH AX
140E:0241 8BC6 MOV AX,SI
140E:0243 99 CWD
140E:0244 52 PUSH DX
140E:0245 50 PUSH AX
140E:0246 8BC6 MOV AX,SI
140E:0248 99 CWD
140E:0249 5B POP BX
140E:024A 59 POP CX
140E:024B 03D8 ADD BX,AX
140E:024D 13CA ADC CX,DX
140E:024F 81C39006 ADD BX,0690
140E:0253 81D100B8 ADC CX,B800
140E:0257 8EC1 MOV ES,CX
140E:0259 58 POP AX
140E:025A 26 ES:
140E:025B 8807 MOV [BX],AL
140E:025D 8A4606 MOV AL,[BP+06]
140E:0260 50 PUSH AX
140E:0261 8BC6 MOV AX,SI
140E:0263 99 CWD
140E:0264 52 PUSH DX
140E:0265 50 PUSH AX
140E:0266 8BC6 MOV AX,SI
140E:0268 99 CWD
140E:0269 5B POP BX
140E:026A 59 POP CX
140E:026B 03D8 ADD BX,AX
140E:026D 13CA ADC CX,DX
140E:026F 81C39106 ADD BX,0691
140E:0273 81D100B8 ADC CX,B800
140E:0277 8EC1 MOV ES,CX
140E:0279 58 POP AX
140E:027A 26 ES:
140E:027B 8807 MOV [BX],AL
140E:027D 46 INC SI
140E:027E 3B7604 CMP SI,[BP+04]
140E:0281 75B2 JNZ 0235
140E:0283 5E POP SI
140E:0284 5D POP BP
140E:0285 C3 RET
showchar函数知道要显示多少个字符是因为main函数给showchar函数传的值8,通过8控制要显示多少字符。printf函数是如何知道多少个函数的呢?我想应该是通过%的个数!但想到%S又有些糊涂了!
于是写了下面程序,生成exe文件用debug跟踪。
main()
{
char a='a',b='b';
printf("%c%c",a,b);
}
在里面找到了这句
140E:0D96 3C25 CMP AL,25 (25为%的ASCII码)
所以猜想是通过%来确定参数个数!
(3)因为才刚学C,对一些语法,程序结构还不清楚,就先到这吧,然后再完成这题!以后补上!
- [游客] 飘过 06/11 13:31
- [fpamc] 貌似我正在步入你的路线……`(*∩_∩*)′Up!Up! 05/24 07:46
- [782936509] 敢问高手你是什么基础开始学的,我没有基础想学编程可以的吗?很想成为一个编程员,希望多多指教,呵呵 12/24 19:26
- [aten] 上面的程序我忘记设置要写入的扇区数了,……-_-~! 08/07 15:50
- [keyia] 啊,如梦初醒!万分感谢 05/28 01:32
- [aten] 好久没来汇编网了,拿你调试的结果来说吧! F:\dosimg\>debug c0s.exe - 05/26 22:52
- [keyia] keyia:变成游客了 05/22 19:42
- [游客] 向您请教: (8)从上我们可以看出tc.exe把c0s.obj和用户obj文件一同进行连接,生成e 05/22 19:40
- [aten] dw 定义的应该是10个字单元,我写成了8个了!所以答案就成了20H 04/26 22:01
- [aten] 恩,^_^ 04/24 18:36
- [游客] 这个,你的那个安装INT9中断程序的程序有一点错误,以下这个是我改正后的: assume cs:c 10/08 07:28
- [游客] 没想到我想走的路和正在走的路你已经走过一遍了,可以的话请加865650570——凌陶 愿我们在同一 10/07 23:30
- [keyia] 向您请教: (8)从上我们可以看出tc.exe把c0s.obj和用户obj文件一同进行连接,生成 05/22 19:44