|
“没有风”的汇编实验报告专题(更新至10)
实验8 分析一个奇怪的程序 分析下面的程序,在运行前思考:这个程序可以正确返回吗? 通过这个程序加深对相关内容的理解。 ;------------------------------------------------------------------------------- ;exp8.asm ;DATE:2007/12/13 ;------------------------------------------------------------------------------- assume cs:codesg codesg segment mov ax,4c00h int 21h start:mov ax,0 ; 占用一个字节的空间,关键,用来添加指令用 s:nop ; 占用一个字节的空间,关键,用来添加指令用 nop ;把标号s处的偏移地址(0008H)传送到DI寄存器 mov di,offset s mov si,offset s2 ;把标号S2处的偏移地址(0020H)传送到SI寄存器 mov ax,cs:[si] ;把代码段处偏移地址为(si)的内容(0F6EBH,即指令JMP SHORT S翻译后为JMP 0008H)传送到AX寄存器,即把标号S2处的指令传送到AX寄存器(关键) mov cs:[di],ax ;把AX内容传送到标号S处(S处有两个字节空间可以用来存入一条指令,关键),相当于在S处添加一条指令JMP SHORT S,机器码为0F6EBH,不过翻译后变为JMP 0000H(好奇怪哦,由原来的JMP 00008H变成这个样子了) s0:jmp short s ;跳转到标号S处执行指令,实际上在上面已经把指令jmp short s复制到了标号S处,因为S为位移值,而不是一个偏移地址,所以执行该指令时,IP寄存器的内容被修改为:S处第二条指令的地址 s1:mov ax,0 int 21h ;(此处指令求被执行) mov ax,0 ;(此处指令求被执行) s2:jmp short s1 ;跳转到标号S1处执行指令,汇编为机器码为0EBF6H,经编译器翻译后为JMP 0018H,关键 nop codesg ends end start ;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov di,offset s mov si,offset s2 这两条指令的功能是把源内存单元的和目的内存单元的偏移地址传送到相应寄存器中去 mov ax,cs:[si] mov cs:[di],ax 这两条指令的功能是将源内存单元的指令传送到目的内存单元中去 将源内存单元的指令jmp short s1 传送到目的去,确切的说应该是将机器指令EBF6H(jmp short s1被DEBUG翻译后的机器码)传送到目的内存单元去.这时,DEBUG把这个机器指令解释出来后,并不是我们原来看到的jmp short s1,因为F6H对应的有符号数为-10D,即当执行jmp short s返回s处执行EBF6H指令时,IP的内容加上JMP指令的长度为10,此时再减去10D,正好CS:IP指向mov ax,4c00h这条指令,接着往下执行程序顺利结束。因此程序可以正常返回。 学了好久,才终于将实验8写完,感觉问题是弄明白了,可是说出来又要让懂的人明白却不是那么容易的一回事。 |
|
[注意]启用“课题+成果”的模式+成立“编程技术小组”(最近更新2008.6.27)
感觉做个词法分析器不是非常难,还是有章可循的,只要有点编译原理的基础,做出个简单的分析器来是不成问题的。 |
|
[注意]启用“课题+成果”的模式+成立“编程技术小组”(最近更新2008.6.27)
大致介绍下自己的技术特长,说明下目前的研究学习方向。技术小组成员的技术或许不是最好的,但对于学习的热情必定是最高的! 技术上没什么特别过人的,不过也能写几行代码。懂点MFC,想深入了解系统是如何运行的。 我想加入这个[编程技术小组],技术虽然不是最好,但非常有激情。目前研究方向是操作系统底层运行原理。 |
|
[己办2期,暂停结束]软件安全系列培训——安全编程
我不是企业用户,只能看望一下。 |
|
|
|
[原创]任意长度的二进制字符串和十进制串的转换算法(高精度)
好主意,我试试看。 |
|
[原创]发一个我写的汇编编译器:虫虫汇编器v0.2
写得非常不错,向你学习。 |
|
[原创]任意长度的二进制字符串和十进制串的转换算法(高精度)
我写的小程序,实现两个功能。第一个:将任意长度的二进制串转换为十进制串,第二个:将任意长度的十进制串转换为二进制串。由于经验不足,有写得不好的地方请多多原谅。 /////////////////////////////////////////// //transformation.h //////////////////////////////////////////// #include <string.h> void Ten2Two(const char* csstrten2two,char* strten2twobin); void Two2Ten(const char* csstrtwo2ten,char* strtwo2tendec); ///////////////////////////////////////////////////////////////////////// //transformation.cpp ///////////////////////////////////////////////////////////////////////// /* **--------------------------------------------------------------------------------------- **函数原型:void Ten2Two(const char* csstrten2two,char* strten2twobin) **功能:将一个任意长度的十进制串转换为一个二进制串 **参数:const char* csstrten2two 要转换的十进制串 char* strten2twobin 转换后的二进制串 **返回值:void **--------------------------------------------------------------------------------------- */ void Ten2Two(const char* csstrten2two,char* strten2twobin) { int istdeclen=strlen(csstrten2two); //存储十进制串的长度 for(int tt=0;tt<istdeclen;tt++){ //如果十进制串为非'0'串(即全部字符为'0')或只有一个字符,提前结束循环 if(csstrten2two[tt]!='0')break; } if(tt==istdeclen){ //如果十进制串为'0'串或只有一个字符,则返回十进制串首字符 strten2twobin[0]=csstrten2two[0]; strten2twobin[1]='\0'; return; } unsigned int k=1; //存储所有十进制串数码或运算的值,如果为0表示十进制数码串为0串 unsigned int quotient=0; //存储余数 int strten2twobinlen=0; //二进制串的长度 int i,j; //循环下标 char ctemp; // char* strten2two=new char[istdeclen+1]; //分配一临时空间,用来存储十进制串转换的数字码(即'0' '1' '2'等对应的数字0 1 2等) for(i=0;i<istdeclen;i++){ //将二进制串转换为数字码并存储到临时空间中去 strten2two[i]=csstrten2two[i]-'0'; } strten2two[i]='\0'; for(i=0;k;i++){ //结束条件为被除数为0 k=0; //赋0,以便下一次再次十进制串的各位数码的或运算值 for(j=0;j<istdeclen;j++){ // while(1){ //把十进制串前面的0过滤掉,不用每次都对十进制串前面的0进行计算 k+=strten2two[j]; // if(k){ k=0; break; } j++; } quotient=(unsigned)(strten2two[j]%2); //求数码除以2的余数,关键 strten2two[j]=(unsigned)strten2two[j]/2; //求数码除以2的商,关键 if(j!=istdeclen-1){ //如果j不是指向最后一位,那位将上一位的余数乘以10加进下一个数去 strten2two[j+1]=(unsigned)(strten2two[j+1]+quotient*10); } for(int tt=0;tt<istdeclen;tt++){ //求所有数码的和 k+=strten2two[tt]; } } strten2twobin[i]=quotient; //除2取余,把所得的余数存储起来,实际上存储的是数字码,关键 strten2twobinlen++; //二进制串的长度加1 } strten2twobin[strten2twobinlen]='\0'; //二进制串未尾加'\0' strten2twobinlen--; //二进制串长度减1,使得该指针指向最后一个字符 for(int t=0;t<=strten2twobinlen;t++,strten2twobinlen--){ //将二进制数字码转换为数字字符,并逆序排列 ctemp=(unsigned)(strten2twobin[t]+'0'); strten2twobin[t]=(unsigned)(strten2twobin[strten2twobinlen]+'0'); strten2twobin[strten2twobinlen]=(unsigned)ctemp; } delete []strten2two; //释放临时分配的空间 } /* **--------------------------------------------------------------------------------------- **函数原型:void Two2Ten(const char* csstrtwo2ten,char* strtwo2tendec) **功能:将一个任意长度的二进制串转换为一个十进制串 **参数:const char* csstrtwo2ten 要转换的二进制串 char* strtwo2tendec 转换后的十进制串 **返回值:void **--------------------------------------------------------------------------------------- */ void Two2Ten(const char* csstrtwo2ten,char* strtwo2tendec) { int istrtwo2tenlen=strlen(csstrtwo2ten); //存储二进制串的长度 int istrtwo2tendeclen=1; //默认十进制串的长度至少为1 int i,j; //循环下标 char ctemp; //临时变量,逆序排列十进制串时使用 char* strtwo2ten=new char[istrtwo2tenlen+1]; //分配一块存储十进制数字码的临时空间 for(i=0;i<istrtwo2tenlen;i++){ //将十进制串转换为数字码并存储到临时空间 strtwo2ten[i]=csstrtwo2ten[i]-'0'; } strtwo2ten[i]='\0'; //加上结束标志,好像也可以不加的 //该循环完成将二进制数码转换为十进制数码的工作,每取一位二进制数,对应的十进制数要乘以2并加上所取的二进制数 for(i=0;i<istrtwo2tenlen;i++){ // for (j=0;j<istrtwo2tendeclen;j++) strtwo2tendec[j]*=2; //每一位十进制数乘2 strtwo2tendec[0]+=strtwo2ten[i]; //十进制数个位加上取得的二进制数 for (j=0;j<istrtwo2tenlen;j++){ // strtwo2tendec[j+1]+=strtwo2tendec[j]/10; //将每一位的前一位分离出十位,前把它加到该位来 strtwo2tendec[j]%=10; //该位被分离后,保留个位不变 } if (strtwo2tendec[istrtwo2tendeclen]) istrtwo2tendeclen++; //如果进来的二进制位使对应十进制数长度增加1 } strtwo2tendec[istrtwo2tendeclen]='\0'; // istrtwo2tendeclen--; // for(i=0;i<=istrtwo2tendeclen;i++,istrtwo2tendeclen--){ //完成两个功能,一是将数字码转换为字母,二是将字符串逆序排列 ctemp=strtwo2tendec[i]+'0'; strtwo2tendec[i]=strtwo2tendec[istrtwo2tendeclen]+'0'; strtwo2tendec[istrtwo2tendeclen]=ctemp; } delete []strtwo2ten; //释放临时分配的空间 } //////////////////////////////////////////// //gaojingduten2two.cpp /////////////////////////////////////////// #include <stdio.h> #include " int main(int argc, char* argv[]) { char str1[40]="35184304988159"; char str2[200]=""; Ten2Two(str1,str2); printf("%s\n",str2); char str3[100]="111111111111111111100000000000001111111111111"; char str4[100]=""; Two2Ten(str3,str4); printf("%s\n",str4); return 0; } ////////////////////////////////////////////////// 输出结果:111111111111111111100000000000001111111111111 35184304988159 |
|
[求助]求一个数值分解的算法
strb.AppendFormat("{0}次{1}\r\n", level.ToString(), NumberStrings); 看不懂这句是什么意思。 不知道楼主想要的是C#,还是其它的呢?小弟不太懂C#。 |
|
[求助]定时器 SetTimer...
厉害,又学到点有用的东西了。 |
|
“没有风”的汇编实验报告专题(更新至10)
楼上朋友不知道能下没有,看不到附件我也不知道是怎么回事啊。因为我也看不到啊。 |
|
[推荐]DataRescue.IDA.Pro.Advanced.v5.2.-YAG(SDK+Hex-Rays.Decompiler.v1.0+相关补丁)
太好了。不过这么复杂,我真的有点看不懂啊。 |
|
[注意]启用“课题+成果”的模式+成立“编程技术小组”(最近更新2008.6.27)
这个我比较感兴趣哦,支持,支持。有目标才不会迷失方向,有方向才能有进步。 |
|
“没有风”的汇编实验报告专题(更新至10)
汇编实验报告七 由于内容太多,在此仅给出源代码。想详细阅读报告的朋友可以下载附件。 ;----------------------------------------------------------------------------------- ;exp7b.asm ;----------------------------------------------------------------------------------- ;AUTHOR:没有风 ;DATE:2007/12/3 ;----------------------------------------------------------------------------------- assume cs:code,ds:data,ss:stack,es:table stack segment ;定义一个堆栈段,用来暂存寄存器的值 dw 16 dup(?) stack ends data segment year db '1975','1976','1977','1978','1979','1980','1981','1982','1983' db '1984','1985','1986','1987','1988','1989','1990','1991','1992' db '1993','1994','1995' income dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514 dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000 employeenum dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226 dw 11542,14430,15257,17800 data ends table segment list db 21 dup ('year summ ne ?? ') ;定义一个长度为21的结构体数组,每个结构体有4个成员 table ends ;分别是年份、总收入、人数、人均收入 code segment start: mov ax,data mov ds,ax mov ax,table mov es,ax mov ax,stack mov ss,ax mov sp,32 mov bx,0 mov si,0 mov di,0 mov cx,21 s: mov ax,84[di] ;取84地址开始的元素,即被除数的低16位 mov dx,86[di] ;取86地址开始的元素,即被除数的高16位 div word ptr 168[si] ;求公司里每年的人均收入 push ax mov ax,[di] ;send the year to table segment mov es:[bx],ax mov ax,[di].2 mov es:[bx].2,ax mov ax,84[di] ;send the income to the table segment mov es:[bx].5,ax mov ax,84[di+2] mov es:[bx].7,ax mov ax,168[si] ;send the employee number to the table segment mov es:[bx+10],ax pop ax mov es:[bx].13,ax ;把商传送到table段中相应内存去,以C的风格访问结构体元素 add di,4 add si,2 add bx,16 loop s mov ax,4c00h int 21h code ends end start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值