. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->综合研究
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  学习王爽汇编语言结束。现提交最后一道作业:24行代码 实现一个简单的 printf 函数!向王老师致敬!  [待解决] 回复[ 1次 ]   点击[ 638次 ]  
yunbing.com
[帖 主]   [ 发表时间:2013-05-14 17:22 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2013-02-26 12:52
/*
  该实现程序之所以能将代码精简到24行(不含空行及注释行),是因为调用了函数:memset,strlen,itoa。
  这三个函数作用分别是清空数组、测试字符数组长度、int转换为char类型。
  这么做不知是否违反了该题的要求?我总感觉题目似乎是要求我们只能用本章第一节所搭建的“精简C语言开发
  环境”来实现,也即任何事情都要亲历亲为,这样才能体会到C语言和汇编语言的内在联系。
  不过在此我也借用王爽老师的“知识屏蔽”理论来为自己开脱一下哈:如果在其他细节上耗费太多的精力,我
  们的研究也就偏离了主题! ^_^
  
  解题思路如下:
  1、循环检测格式字符串 AStr 中的每一个字符;
  2、若该字符为普通字符,直接附加到字符数组 strPrint 的后面;
     若该字符加上后一位字符为“%c”或“%d”,则读取参数列表中相应的参数,转换成字符数组附加到
     strPrint 的后面;
  3、循环将 strPrint 数组中每一个字符输出至屏幕。
  字符显示输出时是仿照试验5的例2,直接输出到显存中,定位在屏幕第10行偏左。
  
  程序在虚拟机 VMware + DOS6.22 + TC2.0 环境下测试通过。
*/

#include <stdlib.h>

void myprintf(char[],...);       /* 函数声明 */

main()
{
    myprintf("It is %c,%d,and %d",'A',18,56);   /* 调用测试 */
}

/* 函数实现
  AStr[]:格式字符数组(字符串),后跟不定数量的 char 或 int 类型参数,但由于受strPrint字符数组大小
  限制,参数并不能无限增加。若需增加参数容量,只需修改该数组大小即可。
  如:char strPrint[1000];
*/
void myprintf(char AStr[],...)
{
    int nCount = 0, nLen, i, nTemp;              /* nCount累计%参数的数量 */
    char strPrint[100] = {0}, strTemp[7] = {0};  /* strPrint字符数组大小决定函数能接受的参数量 */
  
    nLen = strlen(AStr);      /* nLen:格式字符串中的字符数量 */
  
  
    for(i = 0; i<nLen; i++)
    {
        memset(strTemp, 0, 7);     /* 每次循环开始,清空临时字符串 */
    
        /* 如果获取的字符为 %c 或 %d */
        if ((AStr[i] == '%') && ((AStr[i+1] == 'c') || (AStr[i+1] == 'd')))
        {
            nTemp = *(int *)(_BP + 6 + nCount + nCount);   /* 直接从内存获取对应参数值 */
      
            if(AStr[i + 1] == 'c')
                      strTemp[0] = (char)nTemp;        /* 标记为 char 型的则强制转换为字符 */
            else
                      itoa(nTemp, strTemp, 10);        /* 标记为 int 型的转换为字符数组 */
            
            nCount++;        /* nCount累计%参数的数量,以便下一循环调用,为参数寻址 */
            i++;             /* 跳过下一位格式字符 */
        }
        else
        {
            strTemp[0] = AStr[i];    /* 普通字符直接赋值到临时字符串 */
        }    
        strcat(strPrint, strTemp);    /* 临时字符串的字符连接到需打印的字符后面 */
    }
  
    /* 统计需显示的字符个数,应用一个循环将之全部显示到屏幕 */
    nCount = strlen(strPrint); 
    for(i = 0; i < nCount; i++)
        *(char far *)(0xb8000000 + 160 * 10 + 40 + i + i) = strPrint[i];
}
yunbing.com
[第1楼]   [ 回复时间:2013-05-14 17:39 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2013-02-26 12:52
下一阶段的学习是两驾马车齐头并进:
1、谭浩强《C语言程序设计(第2版)》 。惭愧,我有Delphi以及C#的编程经验,但C语言确未学过。不过这本C语言教程目前已经学习完第3章了,所以上面的程序还能通过翻书或百度搜索函数用法,参考一下即可完成。
2、戴水贵《Windows汇编语言程序设计教程》。简单翻看了一下,感觉跟80X86实模式下的汇编有很大的不同,大概是因为不少过程可以直接调用Windows提供的各种函数的缘故吧。
学完这两本应该可以再研究一下软件破解了呵呵~
在此留言自勉一下!
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved