|
主题 : : 研究实验5(2)疑惑,大家帮看下 [待解决] |
回复[ 3次 ]
点击[ 816次 ] | |
荣誉值:0
信誉值:0
注册日期:2008-03-15 23:01 |
(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 //这里为止,将10 个参数压到栈中
140E:0225 E80500 CALL 022D //调用showchar
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 //将a赋为0
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//对应程序中的(_BP+8+a+a),用BX存储栈中相应参数的偏移地址
140E:023E 8A07 MOV AL,[BX]//???????
这里怎么没有将要显示的字符赋给AL呢?默认段地址是DS啊,而字符却在SS段中,虽然偏移地址都是一样的
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] //将颜色属性赋给AL
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]//比较a和n,循环条件
140E:0281 75B2 JNZ 0235
140E:0283 5E POP SI
140E:0284 5D POP BP
140E:0285 C3 RET
所以上面的//?????
我一直不明白,单步跟踪,并没有显示栈中的字符,反而是一个个的空格。而颜色确实是从栈中取出来的,而且颜色也看得到是绿的。
但是,在command中直接运行b.exe可以成功显示8个字符。
这到底是怎么回事呢?
汇编代码中到底哪些指令是将栈中的字符写到显存的呢?我怎么分析都是将数据段中的字节写到显存啊,bx存储的仅仅是偏移地址。
难道数据段和栈段是一样的? | | |