月度存档: 5月 2011

SDCC编译器简明使用教程

先前翻译了SDCC编译器手册第一章的内容,尝试过去翻译其他章节,不过难度似乎比我预计的要大,在google的帮助下也完成不了,现在只能结合自己的使用写点了.

本文以SDCC手册第三章内容为基础!

这里不介绍SDCC的安装过程,作为电气工程专业或者计算机嵌入式方向的学生这不是什么困难的事!安装后把SDCC的bin目录添加到path环境变量使得你能在任何目录下使用SDCC,使用archlinux和debian系统的没有这一步,安装时已经自动配置好了!我平时很少使用集成开发工具(IDE)写代码,所以编辑源代码你可以使用你最拿手的工具,任何文本编辑器都可以,我使用的是vim!

源代码与Keil C的稍许不同

对于已经习惯使用Keil C的用户需要注意一下,SDCC的源代码和Keil C有所不同,需要做一点调整才能编译通过.SDCC比较多的使用像8051.h这样的头文件(include/mcs51目录下也有reg51.h这样的头文件).

对于一些非ANSI C的关键字,SDCC均采用双下滑线开头的方式定义,如__code,__idata,__sbit……对于单片机引脚的定义SDCC采用了__at关键字和十六进制地址(用户对底层地址信息要弄清楚,不过我觉得__at关键字是一个比较有特色的改进),如下:

//SDCC                                      Keil C
__sbit __at 0x94 blackLineLeft;         sbit blackLineLeft=P1^4;
__sbit __at 0x95 blackLineRight;        sbit blackLineRight=P1^5;
__sbit __at 0x80 in1;                   sbit in1=P1^0;
__sbit __at 0x81 in2;                   sbit in2=P1^1;
__sbit __at 0x82 in3                    sbit in3=P1^2;
__sbit __at 0x83 in4;                   sbit in4=P1^3;

更多的地址信息可以查看附录

对于内嵌汇编代码,SDCC使用__asm和__endasm两个关键字,参考代码如下:

void delay0_1(uint n) {
    for(i=0;i

......[......]

Continue

ZOJ 1514 解题报告

Fake Tickets

Time Limit: 1 Seconds Memory Limit: 32768 KB

Your school organized a big party to celebrate your team brilliant win in the prestigious, worldfamous ICPC (International Collegiate Poetry Contest). Everyone in your school was invited for an evening which included cocktail, dinner and a session where your team work was read to the audience. The evening was a success – many more people than you expected showed interested in your poetry – although some critics of yours said it was food rather than words that attracted such an audience.

Whatever the reason, the next day you found out why the school hall had seemed so full: the school director confided he had discovered that several of the tickets used by the guests were fake. The real tickets were numbered sequentially from 1 to N (N <= 10000). The director suspects some people had used the school scanner and printer from the Computer Room to produce copies of the real tickets. The director gave you a pack with all tickets collected from the guests at the party's entrance, and asked you to determine how many tickets in the pack had 'clones', that is, another ticket with the same sequence number.

Input

The input contains data for several test cases. Each test case has two lines. The first line contains two integers N and M which indicate respectively the number of original tickets and the number of persons attending the party (1 <= N <= 10000 and 1 <= M <= 20000). The second line of a test case contains M integers Ti representing the ticket numbers in the pack the director gave you (1 <= Ti <= N). The end of input is indicated by N = M = 0.

Output

For each test case your program should print one line, containing the number of tickets in the pack that had another ticket with the same sequence number.

[……]

Continue

ZJU 1101 解题报告

Gamblers

Time Limit: 1 Seconds Memory Limit: 32768 KB

A group of n gamblers decide to play a game:

At the beginning of the game each of them will cover up his wager on the table and the assitant must make sure that there are no two gamblers have put the same amount. If one has no money left, one may borrow some chips and his wager amount is considered to be negative. Assume that they all bet integer amount of money.

Then when they unveil their wagers, the winner is the one who’s bet is exactly the same as the sum of that of 3 other gamblers. If there are more than one winners, the one with the largest bet wins.

For example, suppose Tom, Bill, John, Roger and Bush bet $2, $3, $5, $7 and $12, respectively. Then the winner is Bush with $12 since $2 + $3 + $7 = $12 and it’s the largest bet.

Input

Wagers of several groups of gamblers, each consisting of a line containing an integer 1 <= n <= 1000 indicating the number of gamblers in a group, followed by their amount of wagers, one per line. Each wager is a distinct integer between -536870912 and +536870911 inclusive. The last line of input contains 0.

Output

For each group, a single line containing the wager amount of the winner, or a single line containing “no solution”.

[……]

Continue

ZJU 1152 解题报告

A Mathematical Curiosity

Time Limit: 1 Seconds Memory Limit: 32768 KB

Given two integers n and m, count the number of pairs of integers (a,b) such that 0 < a < b < n and (a^2+b^2 +m)/(ab) is an integer.

This problem contains multiple test cases!

The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.

The output format consists of N output blocks. There is a blank line between output blocks.

Input

You will be given a number of cases in the input. Each case is specified by a line containing the integers n and m. The end of input is indicated by a case in which n = m = 0. You may assume that 0 < n <= 100.

Output

For each case, print the case number as well as the number of pairs (a,b) satisfying the given property. Print the output for each case on one line in the format as shown below.

[……]

Continue

ZJU 1003 解题报告

Crashing Balloon

Time Limit: 1 Seconds Memory Limit: 32768 KB

On every June 1st, the Children’s Day, there will be a game named “crashing balloon” on TV. The rule is very simple. On the ground there are 100 labeled balloons, with the numbers 1 to 100. After the referee shouts “Let’s go!” the two players, who each starts with a score of “1”, race to crash the balloons by their feet and, at the same time, multiply their scores by the numbers written on the balloons they crash. After a minute, the little audiences are allowed to take the remaining balloons away, and each contestant reports his\her score, the product of the numbers on the balloons he\she’s crashed. The unofficial winner is the player who announced the highest score.

Inevitably, though, disputes arise, and so the official winner is not determined until the disputes are resolved. The player who claims the lower score is entitled to challenge his\her opponent’s score. The player with the lower score is presumed to have told the truth, because if he\she were to lie about his\her score, he\she would surely come up with a bigger better lie. The challenge is upheld if the player with the higher score has a score that cannot be achieved with balloons not crashed by the challenging player. So, if the challenge is successful, the player claiming the lower score wins.

So, for example, if one player claims 343 points and the other claims 49, then clearly the first player is lying; the only way to score 343 is by crashing balloons labeled 7 and 49, and the only way to score 49 is by crashing a balloon labeled 49. Since each of two scores requires crashing the balloon labeled 49, the one claiming 343 points is presumed to be lying.

On the other hand, if one player claims 162 points and the other claims 81, it is possible for both to be telling the truth (e.g. one crashes balloons 2, 3 and 27, while the other crashes balloon 81), so the challenge would not be upheld.

By the way, if the challenger made a mistake on calculating his/her score, then the challenge would not be upheld. For example, if one player claims 10001 points and the other claims 10003, then clearly none of them are telling the truth. In this case, the challenge would not be upheld.

Unfortunately, anyone who is willing to referee a game of crashing balloon is likely to get over-excited in the hot atmosphere that he\she could not reasonably be expected to perform the intricate calculations that refereeing requires. Hence the need for you, sober programmer, to provide a software solution.

[……]

Continue

ZJU 2420 解题报告

Calendar

Time Limit: 1 Seconds Memory Limit: 32768 KB

A calendar is a system for measuring time, from hours and minutes, to months and days, and finally to years and centuries. The terms of hour, day, month, year and century are all units of time measurements of a calender system.

According to the Gregorian calendar, which is the civil calendar in use today, years evenly divisible by 4 are leap years, with the exception of centurial years that are not evenly divisible by 400. Therefore, the years 1700, 1800, 1900 and 2100 are not leap years, but 1600, 2000, and 2400 are leap years.

Given the number of days that have elapsed since January 1, 2000 A.D, your mission is to find the date and the day of the week.

Input

The input consists of lines each containing a positive integer, which is the number of days that have elapsed since January 1, 2000 A.D. The last line contains an integer -1, which should not be processed. You may assume that the resulting date won’t be after the year 9999.

Output

For each test case, output one line containing the date and the day of the week in the format of “YYYY-MM-DD DayOfWeek”, where “DayOfWeek” must be one of “Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday” and “Saturday”.

[……]

Continue

《C程序设计语言》习题解

T1.15,重新编写1.2节中的温度转换程序,使用函数实现温度转换。

#include
int fahrToCel(int fahr)
{
  return 5 * (fahr - 32) / 9;
}
int main()
{
  int fahr, cel;
  int lower, upper, step;
  lower = 0;
  upper = 300;
  step = 20;
  fahr = lower;
  while (fahr < upper) {
      cel = fahrToCel(fahr);
      printf("%d\t%d\n", fahr, cel);
      fahr += step;
  }
  return 0;
}

T1.16,修改打印最长文本行的程序的主程序main,使之可以打印任意长度的输入行的长度,并尽可能多的打印文本。

#include
#define MAXLEN 1000
int getLine(char *s);
void copy(char *to, char *from);
int main()
{
  int len, maxLen;
  char line[MAXLEN], maxLine[MAXLEN];
  maxLen = 0;
  while((len = getLine(line)) != 0) {
      printf("%d %s\n", len, line);
      if(len > maxLen) {
          copy(maxLine, line);
          maxLen = len;
      }
  }
  if(maxLen > 0) printf("%s\n", maxLine);
  return 0;
}
int getLine(char *s)
{
  int i = 0;
  while((s[i] = getchar()) != '\n') i++;
  s[i] = '\0';
  return i;
}
void copy(char *to, char *from)
{
  int i = 0;
  while((to[i] = from[i]) != '\0') i++;
}

[......]

Continue

SDCC第一章手册翻译

最近开始使用SDCC编译器,本来想详细写点SDCC的文章,不过一直没有解决单片机在Linux平台下的烧录问题,所以计划暂时停止了.没事干,先翻译一下 SDCC Manual 第一章的内容!希望对大家有所帮助.不过我这人做事常常有头无尾,所以不太可能把整个手册都翻译好!

SDCC开发比较活跃,不同时期的Manual可能会有些变化,我这翻译的时候Revision是6253.新版本可能会略有一些变化,总体变化不会很大.我的英语不是很好,既不是英语专业的也不是计算机专业的,还不是电气专业的,翻译中难免(可能性很大)会出现的错误,优先建议你去读SDCC Manual的原文,英语不好再考虑对照这篇文章读原文,迫不得已再直接读我的中文翻译.

Chapter 1

简介

1.1 关于SDCC

SDCC(Small Device C Compiler)是 Sandeep Dutta 为8位微处理器设计的开源,可重用,经过优化的ANSI-C交叉编译器.当前版本的目标平台为Intel MCS51兼容单片机(8031, 8032, 8051, 8052系列), Dallas 的 DS80C390 及其衍生产品, Freescale(原属于 Motorola)的 HC08 和基于 Zilog Z80 的兼容单片机.SDCC 也可支持其他单片机,PIC 支持正在开发中.整个编译器源代码在GNU通用公共许可证(GPL)下发布. SDCC 使用 ASXXXX 和 ASLINK 的修改版本作为交叉编译工具和链接工具. SDCC 针对各种单片机进行有效的拓展,可以更好的使用基本的硬件资源.

此外,SDCC 对单片机做了大量标准优化,例如:

  • 全局表达式消除
  • 循环优化(无操作循环优化,归纳变量循环优化,你循环优化)
  • 重复常量合并
  • 复制传播
  • 无效代码清楚
  • switch语句的跳转优化

[……]

Continue