main()
{
*(char *)0x2000='a';
*(int *)0x2000=0xf;
*(char far *)0x20001000='a';
_AX=0x2000;
*(char *)_AX='b';
_BX=0x1000;
*(char *)(_BX+_BX)='a';
*(char far *)(0x20001000+_BX)=*(char *)_AX;
//最好一句是mov byte ptr 2000:(1000+bx) , ds:[ax] bx=1000h , ax=2000h。下面的编译可能有错误
}
1908:01FA 55 PUSH BP
1908:01FB 8BEC MOV BP,SP
1908:01FD C606002061 MOV BYTE PTR [2000],61 ; *(char *)0x2000='a';
1908:0202 C70600200F00 MOV WORD PTR [2000],000F ; *(int *)0x2000=0xf;
1908:0208 BB0020 MOV BX,2000
1908:020B 8EC3 MOV ES,BX
1908:020D BB0010 MOV BX,1000
1908:0210 26 ES:
1908:0211 C60761 MOV BYTE PTR [BX],61 ;*(charfar*)0x20001000='a';
1908:0214 B80020 MOV AX,2000 _AX=0x2000;
1908:0217 8BD8 MOV BX,AX
1908:0219 C60762 MOV BYTE PTR [BX],62 ; *(char *)_AX='b';
1908:021C BB0010 MOV BX,1000 _BX=0x1000;
1908:021F 03DB ADD BX,BX
1908:0221 C60761 MOV BYTE PTR [BX],61 ; *(char *)(_BX+_BX)='a';
1908:0224 8BD8 MOV BX,AX
1908:0226 8A07 MOV AL,[BX] ;取得等号右边的部分,此时_BX=2000H
1908:0228 33C9 XOR CX,CX
1908:022A 81C30010 ADD BX,1000 _BX=3000H
1908:022E 81D10020 ADC CX,2000
1908:0232 8EC1 MOV ES,CX
1908:0234 26 ES: *(char far *)(0x20001000+_BX)=*(char *)_AX;
1908:0235 8807 MOV [BX],AL
1908:0237 5D POP BP
1908:0238 C3 RET
应该是给es:2000的,怎么给了es:3000
-d es:3000
2000:3000 61 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 a...............
2、在屏幕中间显示一个绿色的’a’
main()
{
*(int far *)(0xb8000000+160*12+80)=0x0261;
}
3、
主函数
1908:01FA 55 PUSH BP
1908:01FB 8BEC MOV BP,SP
1908:01FD 83EC06 SUB SP,+06
1908:0200 C706A6010A00 MOV WORD PTR [01A6],000A
1908:0206 C706A801A200 MOV WORD PTR [01A8],00A2
1908:020C C706AA01A300 MOV WORD PTR [01AA],00A3
1908:0212 C746FAB100 MOV WORD PTR [BP-06],00B1
1908:0217 C746FCB200 MOV WORD PTR [BP-04],00B2
1908:021C C746FEB300 MOV WORD PTR [BP-02],00B3
1908:0221 8BE5 MOV SP,BP
1908:0223 5D POP BP
1908:0224 C3 RET
F函数(在主函数下面)
1908:0225 55 PUSH BP
1908:0226 8BEC MOV BP,SP
1908:0228 83EC06 SUB SP,+06
1908:022B C706A601FA00 MOV WORD PTR [01A6],00FA
1908:0231 C706A801A20F MOV WORD PTR [01A8],0FA2
1908:0237 C706AA01A30F MOV WORD PTR [01AA],0FA3
1908:023D C746FA0C00 MOV WORD PTR [BP-06],000C
1908:0242 C746FCC200 MOV WORD PTR [BP-04],00C2
1908:0247 C746FEC300 MOV WORD PTR [BP-02],00C3
1908:024C 8BE5 MOV SP,BP
1908:024E 5D POP BP
1908:024F C3 RET
从上面两个函数可以看出,C语言把全局变量放在数据段中,把局部变量放在在进入函数前先入栈,然后通过push sp (保护sp中的数据) mov bp,sp (sp指向栈顶)通过bp+偏移指向每个局部变量
4、
主函数
1908:01FA 55 PUSH BP
1908:01FB 8BEC MOV BP,SP
1908:01FD 83EC02 SUB SP,+02;空出局部变量的内存
1908:0200 E80700 CALL 020A
1908:0203 8946FE MOV [BP-02],AX
1908:0206 8BE5 MOV SP,BP
1908:0208 5D POP BP
1908:0209 C3 RET
F函数
1908:020A 55 PUSH BP
1908:020B 8BEC MOV BP,SP
1908:020D A1A601 MOV AX,[01A6]
1908:0210 0306A801 ADD AX,[01A8]
1908:0214 A3AA01 MOV [01AA],AX
1908:0217 A1AA01 MOV AX,[01AA]
1908:021A EB00 JMP 021C
1908:021C 5D POP BP ;没有 mov sp,bp编译器则么知道sp没有变过
1908:021D C3 RET
可以看出C语言的返回值放在AX中
如果给f函数传参呢?会怎么样?
传参以后的f函数
1908:020E 55 PUSH BP
1908:020F 8BEC MOV BP,SP
1908:0211 A1A601 MOV AX,[01A6]
1908:0214 0306A801 ADD AX,[01A8]
1908:0218 A3AA01 MOV [01AA],AX
1908:021B A1AA01 MOV AX,[01AA]
1908:021E 894604 MOV [BP+04],AX
1908:0221 A1AA01 MOV AX,[01AA]
1908:0224 EB00 JMP 0226
1908:0226 5D POP BP
1908:0227 C3 RET
5、
#define Buffer ((char*) *(int far *)0x20000000)
这一句的宏定义的意思是:给2000:0000这个字内存取了个新名字:Buffer,并且规定以Buffer为地址的内存是字节型的
main()
{
Buffer=(char *)malloc(20);
Buffer[10]=0;
while(Buffer[10]!=8)
{
Buffer[Buffer[10]]='a'+Buffer[10];
Buffer[10]++;
}
}
1908:01FA 55 PUSH BP
1908:01FB 8BEC MOV BP,SP
1908:01FD B81400 MOV AX,0014
1908:0200 50 PUSH AX
1908:0201 E8D902 CALL 04DD
1908:0204 59 POP CX//cx中存有地址
1908:0205 BB0020 MOV BX,2000
1908:0208 8EC3 MOV ES,BX
1908:020A 33DB XOR BX,BX
1908:020C 26 ES:
1908:020D 8907 MOV [BX],AX//2000:0000=20
1908:020F BB0020 MOV BX,2000
1908:0212 8EC3 MOV ES,BX
1908:0214 33DB XOR BX,BX
1908:0216 26 ES:
1908:0217 8B1F MOV BX,[BX]
1908:0219 C6470A00 MOV BYTE PTR [BX+0A],00//2000:000a=0
1908:021D EB3C JMP 025B
1908:021F BB0020 MOV BX,2000
1908:0222 8EC3 MOV ES,BX
1908:0224 33DB XOR BX,BX
1908:0226 26 ES:
1908:0227 8B1F MOV BX,[BX]
1908:0229 8A470A MOV AL,[BX+0A]
1908:022C 0461 ADD AL,61//取出字符
1908:022E BB0020 MOV BX,2000
1908:0231 8EC3 MOV ES,BX
1908:0233 33DB XOR BX,BX
1908:0235 26 ES:
1908:0236 8B1F MOV BX,[BX]
1908:0238 50 PUSH AX
1908:0239 53 PUSH BX
1908:023A BB0020 MOV BX,2000
1908:023D 8EC3 MOV ES,BX
1908:023F 33DB XOR BX,BX
1908:0241 26 ES:
1908:0242 8B1F MOV BX,[BX]
1908:0244 8A470A MOV AL,[BX+0A]
1908:0247 98 CBW
1908:0248 5B POP BX
1908:0249 03D8 ADD BX,AX
1908:024B 58 POP AX
1908:024C 8807 MOV [BX],AL
1908:024E BB0020 MOV BX,2000
1908:0251 8EC3 MOV ES,BX
1908:0253 33DB XOR BX,BX
1908:0255 26 ES:
1908:0256 8B1F MOV BX,[BX]
1908:0258 FE470A INC BYTE PTR [BX+0A]
1908:025B BB0020 MOV BX,2000
1908:025E 8EC3 MOV ES,BX
1908:0260 33DB XOR BX,BX
1908:0262 26 ES:
1908:0263 8B1F MOV BX,[BX]
1908:0265 807F0A08 CMP BYTE PTR [BX+0A],08//判断循环结束条件
1908:0269 75B4 JNZ 021F
1908:026B 5D POP BP
1908:026C C3 RET
- [cutebe] 相当牛,这个苦思冥想也值了。^_^ 11/30 00:00
- [parse] 如果忽略消息循环,那么操作系统加载的程序很快就执行完了,就像DOS程序一闪而过,所以CPU会空闲下来 06/30 09:04
- [游客] 楼主好厉害,挺一下! 01/19 08:43
- [游客] 很不错。 01/04 18:36
- [chinatree] 潜力贴留名,沙发。 11/08 12:58
- [youthangel] 恩,这次对了 10/30 18:56
- [fpamc] mov bx,18 在这条指令的上边是不是要加一条sub dx,dx? 10/30 10:03
- [fpamc] 对的 10/27 11:19
- [fpamc] 对的 10/27 09:00
- [fpamc] 哦,对不起,看错了。实验13也有一个7ch中断 10/27 08:52
- [游客] 现在急需一个汇编大作业。。。。。。可以么。。。。。如果今天之内看见留言 就加 1765496715 12/28 16:52
- [youthangel] 这算是对我学习的鼓励吗?谢谢!咱们这样交流就可以了 10/11 15:48
- [fpamc] 多日观察,你的学习积极性挺高的。可以来我们群了。群号:75916434 10/11 10:58