微信小程序 > 微信公开课 > 汇编语言做的小程序
微信小程序,微信公开课,汇编语言做的小程序

汇编语言做的小程序

2019-03-12 17:02:19

微信公开课小程序热门讨论「汇编语言做的小程序」最新回复-代码+注释承上.386.modelflat,stdcall;这里我们用stdcall就是函数参数压栈的时候从最后一个开始压,和被调用函数负责清栈optioncasemap:none;区分大小写includelibmsvcrt.lib;这里是引入类库相当于#includestdio.h了printfPROTOC:DWORD,:VARARG;这个就是声明一下我们要用的函数头,到时候汇编程序会自动到msvcrt.lib里面找的了;:VARARG表后面的参数不确定因为C就是这样的printf(constchar*,...);;这样的函数要注意不是被调用函数负责清栈因为它本身不知道有多少个参数;而是有调用者负责清栈下面会详细说明.dataszTextFmtBYTE%d,0;这个是用来类型转换的,跟C的一样,字符用字节类型adword1000;假设bdword2000;处理数值都用双字没有int跟long的区别;/////////////////////////////////////////////////////////////////////////////////////////.code_testproc;A:DWORD,B:DWORDpushebpmovebp,espmoveax,dwordptrss:[ebp+8]addeax,1movedx,dwordptrss:[ebp+0Ch]addedx,100addeax,edxpopebpretn8_testendp_mainprocpushdwordptrds:b;反汇编我们看到的b就不是b了而是一个[*****]数字dwordptr就是我们在ds(数据段)把[*****];开始的一个双字长数值取出来pushdwordptrds:a;跟她对应的还有byteptr****就是取一个字节出来比如这样moval,byteptrds:szTextFmt;就把%取出来而不包括dcall_testpusheax;假设pusheax的地址是×××××pushoffsetszTextFmtcallprintfaddesp,8ret_mainendpend_main;//////////////////////////////////////////////////////////////下面介绍堆栈的变化首先要明白的是操作堆栈段ss只能用esp或ebp寄存器其他的寄存器eaxebxedx等都不能够用而esp永远指向堆栈栈顶ebp用来在堆栈段里面寻址push指令是压栈ESP=ESP4pop指令是出栈ESP=ESP+4我们假设main函数一开始堆栈定是ESP=400pushdwordptrds:b;ESP4=396里面的值就是2000就是b的数值pushdwordptrds:a;ESP4=392里面的值就是1000就是a的数值calltest;ESP4=388-里面的数值是什么?这个太重要了就是我们用来找游戏函数的原理所在。里面的数值就是calltest指令下一条指令的地址-即pusheax的地址×××××到了test函数里面pushebp;ESP4=384里面保存了当前ebp的值而不是把ebp清零movebp,esp;这里ESP=384就没变化了,但是ebp=esp=384,为什么要这样做呢因为我们要用ebp到堆栈里面找参数moveax,dwordptrss:[ebp+8];反汇编是这样的想想为什么a就是[ebp+8]呢;我们往上看看堆栈里地址392处就保存着a的值这里ebp=384加上8正好就是392了;这样就把传递过来的1000拿了出来eax=1000addeax,1;相当于a+1了eax=1001movedx,dwordptrss:[ebp+0Ch];0Ch=12一样道理这里指向堆栈的地址是384+12=396就是2000了edx=2000addedx,100;相当于b+100edx=2100addeax,edx;eax=eax+edx=1001+2100=3101这里eax已经保存了最终的结果了;因为win32汇编一般用eax返回结果所以如果最终结果不是在eax里面的话还要把它放到eax;比如假设我的结果保存在变量nRet里面最后还是要这样moveax,dwordptrnRetpopebp;ESP=384+4=388而保存在栈顶384的值保存到ebp中即恢复ebp原来的值;因为一开始我们就把ebp的值压栈了,movebp,esp已经改变了ebp的值,这里恢复就是保证了堆栈平衡retn8;ESP+8396这里retn是由系统调用的我们不用管系统会自动把EIP指针指向原来的call的下一条指令;由于是系统自动恢复了call那里的压栈所以真正返回到的时候ESP+4就是恢复了call压栈的堆栈;到了这个时候ESP=400就是函数调用开始的堆栈,就是说函数调用前跟函数调用后的堆栈是一样的;这就是堆栈平衡由于我们用stdcall上面retn8就是被调用者负责恢复堆栈的意思了,函数test是被调用者,所以负责把堆栈加8,call那里是系统自动恢复的pusheax;ESP4=396里面保存了eax的值3101;上面已经看到了eax保存着返回值,我们要把它传给printf也是通过堆栈传递pushoffsetszTextFmt;ESP4=392里面保存了szTextFmt的地址也就是C里面的指针实际上没有什么把字符串传递的,我们传的都是地址;无论是在汇编或C所以在汇编里没有什么字符串类型用最多的就是DWORD。嘿嘿游戏里面传递参数简单多了callprintf;ESP4=388里面保存了下一条指令的地址addesp,8;ESP+8=400恢复了调用printf前的堆栈状态;上面说了由于printf后面参数是:VARARG这样的类型是有调用者恢复堆栈的所以printf里面没有retn8之类的指令;这是由调用者负责清栈main是调用者所以下面一句就是addesp,8把堆栈恢复到调用printf之前;而callprintf那里的压栈是由系统做的恢复的工作也是系统完成我们不用理只是知道里面保存是返回地址就够;了ret;main函数返回其他的事情是系统自动搞定我们不用理任务完成
;;;;;;;;;;;本实验用T0计时;;;;;;;;;;;;;P3.2接按键K1用来调小时,按一下加1,加到23再按跳到1,P3.3调分钟,P3.4按下自动计时开;;;;;;;;;;;;;;;;始,P3.5调秒钟P0接了两个锁存器,一个锁存器接6数码管段码,一锁存器接数码管位码dsegat  0030hsecond:ds1minite:ds1hour:ds1disbuff:ds6csegat  0000hjmp  startcsegat  1*8+3jmpt0_interruptstart:movP0,#00hmovr7,#40movr6,#100movsecond,#0movminite,#0movhour,#0callt0_initsetbEAlp:callloopcallbuttonsjmplpsjmp$t0_interrupt:pushaccpushpswdjnzr7,t0_returnmov  r7,#40djnzr6,t0_return  mov  r6,#100cpl  P1.0inc  secondmov  a,secondxrl  a,#60jnz  t0_return mov  second,ainc  minitecpl  P1.1mov  a,minitexrl  a,#60jnz  t0_returnmov  minite,ainc  hourcpl  P1.2mov  a,hourxrl  a,#24jnz  t0_returnmov  hour,at0_return:pop  pswpop  accretit0_init:mov  TMOD,#02hmov  TH0,#-250mov  TL0,#-250setbTR0setbET0retdelay:mov  r4,#200for1:nop  nop  nop  djnzr4,for1  rettab:DB  0C0H,0F9H,0A4H,0B0HDB  99H,92H,82H,0f8HDB  80H,90H,88H,83HDB  0c6H,0a1H,86H,8eHloop:mov  a,secondmov  B,#10div  ABmov  disbuff+0,a  mov  dptr,#tabmovc  a,@a+dptrmov  P0,asetb  P1.3nopclr  P1.3mov  P0,#00000010bsetb  P1.2nopclr  P1.2call  delaymov  disbuff+1,bmov  a,Bmovc  a,@a+dptrmov  P0,asetb  P1.3nopclr  P1.3mov  P0,#00000001bsetb  P1.2nopclr  P1.2call  delaymov  a,minite  mov  B,#10div  ABmov  disbuff+2,amov  dptr,#tabmovc  a,@a+dptrmov  P0,asetb  P1.3nopclr  P1.3mov  P0,#00001000bsetb  P1.2nopclr  P1.2call  delaymov  disbuff+3,bmov  a,Bmovc  a,@a+dptranl  a,#01111111b //小数点mov  P0,asetb  P1.3nopclr  P1.3mov  P0,#00000100bsetb  P1.2nopclr  P1.2call  delaymov  a,hour  mov  B,#10div  ABmov  disbuff+4,amov  dptr,#tabmovc  a,@a+dptrmov  P0,asetb  P1.3nopclr  P1.3mov  P0,#00100000bsetb  P1.2nopclr  P1.2call  delaymov  disbuff+5,bmov  a,Bmovc  a,@a+dptranl  a,#01111111b//小数点mov  P0,asetb  P1.3nopclr  P1.3mov  P0,#00010000bsetb  P1.2nopclr  P1.2call  delayretbutton:jnbP3.2,hour_addadd_1:jnbP3.3,minite_addadd_2:jnbP3.5,second_addauto:  jnbP3.4,TR0_SETBsjmpreturnhour_add:jnbP3.2,$clrTR0inchour  mova,hour  xrla,#24  jzclr_hour  sjmpadd_1minite_add:  jnbP3.3,$clrTR0incminite  mova,minite  xrla,#60  jzclr_minite  sjmpadd_2second_add:  jnbP3.5,$clrTR0incsecond  mova,second  xrla,#60  jzclr_second  sjmpautoclr_hour:mov  hour,#0  sjmpadd_1clr_minite:  movminite,#0  sjmpadd_2clr_second:  movsecond,#0  sjmpautoTR0_SETB:setbTR0return:retend 更多有关「汇编语言做的小程序」的疑问请扫码关注微信公开课+小程序!
标签:微信公开课,小程序
微信小程序,微信公开课,汇编语言做的小程序

「汇编语言做的小程序」热议话题订阅

方法1:微信扫描微信公开课小程序码即可订阅热议话题「汇编语言做的小程序」

方法2:微信搜索微信公开课小程序名称进入,即可订阅热议话题「汇编语言做的小程序」

方法3:微信网页访问即速商店,长按识别微信公开课小程序码即可订阅热议话题「汇编语言做的小程序」

微信公开课小程序热议话题「汇编语言做的小程序」由微信公开课原创摘录于微信小程序商店shop.jisuapp.cn,转载请注明出处。

微信公开课热议话题「汇编语言做的小程序」由微信公开课开发者向微信用户提供,并对本服务内容、数据资料及其运营行为等真实性、合法性及有效性承担全部责任。