<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dutor &#187; 汇编</title>
	<atom:link href="http://www.dutor.net/index.php/tag/asm/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dutor.net</link>
	<description>熟读而精思，循序而渐进，厚积而薄发。</description>
	<lastBuildDate>Tue, 17 Jan 2012 14:44:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>[转摘]代码优化概要</title>
		<link>http://www.dutor.net/index.php/2010/09/overlooked-essentials-for-optimizing-code/</link>
		<comments>http://www.dutor.net/index.php/2010/09/overlooked-essentials-for-optimizing-code/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 03:54:21 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2445</guid>
		<description><![CDATA[　　我编写程序至今有35年了，我做了很多关于程序执行速度方面优化的工(一个示例)，我也看过其它人做的优化。我发现有两个最基本的优化技术总是被人所忽略。
　　注意，这两个技术并不是避免时机不成熟的优化。并不是把冒泡排序变成快速排序（算法优化）。也不是语言或是编译器的优化。也不是把 i*4写成i<<2的优化。

　　这两个技术是：
<ul>
	<li>使用 一个profiler。</li>
	<li>查看程序执行时的汇编码。</li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>　　本文由<a href="http://coolshell.cn/articles/2967.html" target="_blank">陈皓</a>译自Dr. Dobb’s Blogger的Walter Bright写的《<a href="http://www.drdobbs.com/blog/archives/2010/09/overlooked_esse.html" target="_blank">Overlooked Essentials For Optimizing Code</a>》.</p>
<hr />
　　我编写程序至今有35年了，我做了很多关于程序执行速度方面优化的工(一个示例)，我也看过其它人做的优化。我发现有两个最基本的优化技术总是被人所忽略。<br />
　　注意，这两个技术并不是避免时机不成熟的优化。并不是把冒泡排序变成快速排序（算法优化）。也不是语言或是编译器的优化。也不是把 i*4写成i<<2的优化。</p>
<p>　　这两个技术是：</p>
<ul>
<li>使用 一个profiler。</li>
<li>查看程序执行时的汇编码。</li>
</ul>
<p>　　使用这两个技术的人将会成功地写出运行快的代码，不会使用这两个技术的人则不行。下面让我为你细细道来。</p>
<h4>使用一个 Profiler</h4>
<p>　　我们知道，程序运行时的90%的时间是用在了10%的代码上。我发现这并不准确。一次又一次地，我发现，几乎所有的程序会在1%的代码上花了99%的运行时间。但是，是哪个1%？一个好的Profiler可以告诉你这个答案。就算我们需要使用100个小时在这1%的代码上进行优化，也比使用100个小时在其它99%的代码上优化产生的效益要高得多得多。</p>
<p>　　问题是什么？人们不用profiler？不是。我工作过的一个地方使用了一个华丽而奢侈的Profiler，但是购买这个Profiler后，它的包装3年还是那么的暂新。为什么人们不用？我真的不知道。有一次，我和我的同事去了一个负载过大的交易所，我同事坚持说他知道哪里是瓶颈，毕竟，他是一个很有经验的专家。最终，我把我的Profiler在他的项目上运行了一下，我们发现那个瓶颈完全在一个意想不到的地方。</p>
<p>　　就像是赛车一样。团队是赢在传感器和日志上，这些东西提供了所有的一切。你可以调整一下赛车手的裤子以让其在比赛过程中更舒服，但是这不会让你赢得比赛，也不会让你更有竞争力。如果你不知道你的速度上不去是因为引擎、排气装置、空体动力学、轮胎气压，或是赛车手，那么你将无法获胜。编程为什么会不同呢？只要没有测量，你就永远无法进步。</p>
<p>　　这个世界上有太多可以使用的Profiler了。随便找一个你就可以看到你的函数的调用层次，调用的次数，以前每条代码的时间分解表（甚至可以到汇编级）。我看过太多的程序员回避使用Profiler，而是把时间花在那些无用的，错误的方向上的“优化”，而被其竞争对手所羞辱。（译者陈皓注：使用Profiler时，重点需要关注：1）花时间多的函数以优化其算法，2）调用次数巨多的函数——如果一个函数每秒被调用300K次，你只需要优化出0.001毫秒，那也是相当大的优化。这就是作者所谓的1%的代码占用了99%的CPU时间）</p>
<h4>查看汇编代码</h4>
<p>几年前，我有一个同事，Mary Bailey，她在华盛顿大学教矫正代数（remedial algebra），有一次，她在黑板上写下：</p>
<p>x + 3 = 5</p>
<p>然后问他的学生“求解x”，然后学生们不知道答案。于是她写下：</p>
<p>__ + 3 = 5</p>
<p>　　然后，再问学生“填空”，所有的学生都可以回答了。未知数x就像是一个有魔法的字母让大家都在想“x意味着代数，而我没有学过代数，所以我就不知道这个怎么做”。</p>
<p>　　汇编程序就是编程世界的代数。如果某人问我“inline函数是否被编译器展开了？”或是问我“如果我写下i*4，编译器会把其优化为左移位操作吗？”。这个时候，我都会建议他们看看编译器的汇编码。这样的回答是不是很粗暴和无用？通常，在我这样回答了提问者后，提问都通常都会说，对不起，我不知道什么是汇编！甚至C++的专家都会这么回答。</p>
<p>　　汇编语言是最简单的编程语言了（就算是和C++相比也是这样的），如：</p>
<p>ADD ESI,x</p>
<p>就是（C风格的代码）</p>
<p>ESI += x;</p>
<p>而：</p>
<p>CALL foo</p>
<p>则是：</p>
<p>foo();</p>
<p>　　细节因为CPU的种类而不同，但这就是其如何工作的。有时候，我们甚至都不需要细节，只需要看看汇编码的长啥样，然后和源代码比一比，你就可以知道汇编代码很多很多了。</p>
<p>　　那么，这又如何帮助代码优化？举个例子，我几年前认识一个程序员认为他应该去发现一个新的更快的算法。他有一个benchmark来证明这个算法，并且其写了一篇非常漂亮的文章关于他的这个算法。但是，有人看了一下其原来算法以及新算法的汇编，发现了他的改进版本的算法允许其编译器把两个除法操作变成了一个。这和算法真的没有什么关系。我们知道除法操作是一个很昂贵的操作，并且其还在一个内嵌循环中，所以，他的改进版的算法当然要快一些。只需要在原来的算法上做一点点小的改动——使用一个除法操作，那么其原来的算法将会和新的一样快。而他的新发现什么也不是。</p>
<p>　　下一个例子，一个D用户张贴了一个 benchmark 来显示 dmd (Digital Mars D 编译器)在整型算法上的很糟糕，而ldc (LLVM D 编译器) 就好很多了。对于这样的结果，其相当的有意见。我迅速地看了一下汇编，发现两个编译器编译出来相当的一致，并没有什么明显的东西要对2：1这么大的不同而负责。但是我们看到有一个对long型整数的除法，这个除法调用了运行库。而这个库成为消耗时间的杀手，其它所有的加减法都没有速度上的影响。出乎意料地，benchmark 和算法代码生成一点关系也没有，完全就是long型整数的除法的问题。这暴露了在dmd的运行库中的long型除法的实现很差。修正后就可以提高速度。所以，这和编译器没有什么关系，但是如果不看汇编，你将无法发现这一切。</p>
<p>　　查看汇编代码经常会给你一些意想不到的东西让你知道为什么程序的性能是那样。一些意想不到的函数调用，预料不到的自傲，以及不应该存在的东西，等等其实所有的一切。但也不需要成为一个汇编代码的黑客才能干的事。</p>
<h4>结论</h4>
<p>　　如果你觉得需要程序有更好的执行速度，那么，最基本的方法就是使用一个profiler和愿意去查看一下其汇编代码以找到程序的瓶颈。只有找到了程序的瓶颈，此时才是真正在思考如何去改进的时候，比如思考一个更好的算法，使用更快的语言优化，等等。</p>
<p>　　常规的做法是制胜法宝是挑选一个最佳的算法而不是进行微优化。虽然这种做法是无可异议的，但是有两件事情是学校没有教给你而需要你重点注意的。第一个也是最重要的，如果你优化的算法没没有参与到你程序性能中的算法，那么你优化他只是在浪费时间和精力，并且还转移了你的注意力让你错过了应该要去优化的部分。第二点，算法的性能总和处理的数据密切相关的，就算是冒泡排序有那么多的笑柄，但是如果其处理的数据基本是排好序的，只有其中几个数据是未排序的，那么冒泡排序也是所有排序算法里性能最好的。所以，担心没有使用好的算法而不去测量，只会浪费时间，无论是你的还是计算机的。</p>
<p>　　就好像赛车零件的订购速底是不会让你更靠进冠军（就算是你正确安装零件也不会），没有Profiler，你不会知道问题在哪里，不去看汇编，你可能知道问题所在，但你往往不知道为什么。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/09/overlooked-essentials-for-optimizing-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PIC18 EEPROM编程</title>
		<link>http://www.dutor.net/index.php/2009/11/pic18-eeprom/</link>
		<comments>http://www.dutor.net/index.php/2009/11/pic18-eeprom/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 14:25:04 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[尚未分类]]></category>
		<category><![CDATA[单片机]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1720</guid>
		<description><![CDATA[　　本程序利用PIC18单片机实现了对EEPROM的读写。应用背景是"汽车里程表"，简单介绍下程序功能和流程。
　　单片机接受来自RA4管脚的计数脉冲信号，应用中这个脉冲信号通常由一个传感器来产生，计数脉冲被设定为上升沿触发。计数器溢出时，需要更新一个用于存储当前里程的RAM寄存器单元COUNT，可以理解为车轮转了一定圈数后，里程表的增加一定的里程数。
　　RB0管脚用来接收一个外部中断信号，接收到中断信号后，在中断服务程序中将COUNT的值即当前里程数保存至EEPROM的00H单元。这样可以配合外部电路实现当单片机掉电时自动保存里程表数值的功能，即汽车熄火时保存里程表，以减少对EEPROM的读写次数。
　　单片机启动时，首先应该到EEPROM的相应单元读取里程表的当前值，并在此基础上进行累加。
　　程序中为了调试方便，还将COUNT的数值同步地通过8个LED以二进制形式较直观地显示了出来。 
<pre lang="asm" line="1">
LOOP	
		
	BCF	INTCON, T0IF 	; 清TMR0中断标志
	MOVLW	TMR0B 
	MOVWF	TMR0L 		; 装入计数初值 253
	BSF	T0CON, TMR0ON 	; 启动计数器
	TEST	
	BTFSS	INTCON, T0IF 	; 检测TMR0是否溢出
	GOTO	TEST
	INCF	COUNT, F 	; 计数加一
	MOVFF	COUNT, PORTD 	; 输出，显示
		
	GOTO	LOOP
		
WIRT_EE				; 写EEPROM
	BCF	EECON1, EEPGD
	BCF	EECON1, CFGS 	; 设定EECON1控制寄存器
	BSF	EECON1, WREN 	; EEPROM写使能
	BCF	INTCON, GIE 	; 写EEPROM时需要关闭一切中断
</pre>]]></description>
			<content:encoded><![CDATA[<p>　　本程序利用PIC18单片机实现了对EEPROM的读写。应用背景是&#8221;汽车里程表&#8221;，简单介绍下程序功能和流程。<br />
　　单片机接受来自RA4管脚的计数脉冲信号，应用中这个脉冲信号通常由一个传感器来产生，计数脉冲被设定为上升沿触发。计数器溢出时，需要更新一个用于存储当前里程的RAM寄存器单元COUNT，可以理解为车轮转了一定圈数后，里程表的增加一定的里程数。<br />
　　RB0管脚用来接收一个外部中断信号，接收到中断信号后，在中断服务程序中将COUNT的值即当前里程数保存至EEPROM的00H单元。这样可以配合外部电路实现当单片机掉电时自动保存里程表数值的功能，即汽车熄火时保存里程表，以减少对EEPROM的读写次数。<br />
　　单片机启动时，首先应该到EEPROM的相应单元读取里程表的当前值，并在此基础上进行累加。<br />
　　程序中为了调试方便，还将COUNT的数值同步地通过8个LED以二进制形式较直观地显示了出来。</p>

<div class="wp_codebox"><table><tr id="p17201"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
</pre></td><td class="code" id="p1720code1"><pre class="asm" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">list</span>	P = 18F452
#include P18F452<span style="color: #339933;">.</span><span style="color: #00007f; font-weight: bold;">INC</span>
&nbsp;
	TMR0B	EQU D<span style="color: #7f007f;">'253'</span>
	COUNT	EQU  0x10H
	<span style="color: #000000; font-weight: bold;">ORG</span>	<span style="color: #0000ff;">0000H</span>	  	<span style="color: #666666; font-style: italic;">;PIC上电时从0000h单元开始执行</span>
	<span style="color: #000000; font-weight: bold;">GOTO</span>	MAIN	  	<span style="color: #666666; font-style: italic;">;跳转到主程序</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">ORG</span>	<span style="color: #0000ff;">0008H</span>
	<span style="color: #000000; font-weight: bold;">GOTO</span>	INT0_ISR	<span style="color: #666666; font-style: italic;">;中断向量入口</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">ORG</span>	<span style="color: #0000ff;">0030H</span>	  	<span style="color: #666666; font-style: italic;">;主程序定位</span>
MAIN	
	CLRF	TRISD	  	<span style="color: #666666; font-style: italic;">;设定D口方向为输出</span>
	CLRF	PORTD 		<span style="color: #666666; font-style: italic;">;设定C口方向为输出</span>
	<span style="color: #00007f; font-weight: bold;">BSF</span>	TRISA<span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span> 	<span style="color: #666666; font-style: italic;">; 使用RA4做为计数输入</span>
	<span style="color: #00007f; font-weight: bold;">BSF</span>	INTCON<span style="color: #339933;">,</span> GIE 	<span style="color: #666666; font-style: italic;">;开全局中断</span>
	BCF	INTCON<span style="color: #339933;">,</span> INT0IF 	<span style="color: #666666; font-style: italic;">;清INT0中断标志</span>
	<span style="color: #00007f; font-weight: bold;">BSF</span>	INTCON<span style="color: #339933;">,</span> INT0IE 	<span style="color: #666666; font-style: italic;">; 开INT0中断</span>
	<span style="color: #00007f; font-weight: bold;">BSF</span>	TRISB<span style="color: #339933;">,</span> INT0 	<span style="color: #666666; font-style: italic;">; 设定RB0即INT0脚为接收(输入)状态</span>
&nbsp;
	MOVLW	<span style="color: #0000ff;">68H</span>
	MOVWF	T0CON 		<span style="color: #666666; font-style: italic;">; 设定计数器TMR0为8位计数，上升沿触发，分频比1:1</span>
	MOVLW	<span style="color: #0000ff;">0x00</span>
	MOVWF	EEADR	 	<span style="color: #666666; font-style: italic;">; 装载EEPROM的地址00h</span>
	<span style="color: #00007f; font-weight: bold;">CALL</span>	READ_EE 	<span style="color: #666666; font-style: italic;">; 读入EEPROM中00h单元的原始数据，即计数初值，保存到WREG</span>
	MOVWF	COUNT
	MOVWF	PORTD 		<span style="color: #666666; font-style: italic;">; 输出到PORTD(连接了8个LED)</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">LOOP</span>	
&nbsp;
	BCF	INTCON<span style="color: #339933;">,</span> T0IF 	<span style="color: #666666; font-style: italic;">; 清TMR0中断标志</span>
	MOVLW	TMR0B 
	MOVWF	TMR0L 		<span style="color: #666666; font-style: italic;">; 装入计数初值 253</span>
	<span style="color: #00007f; font-weight: bold;">BSF</span>	T0CON<span style="color: #339933;">,</span> TMR0ON 	<span style="color: #666666; font-style: italic;">; 启动计数器</span>
	<span style="color: #00007f; font-weight: bold;">TEST</span>	
	BTFSS	INTCON<span style="color: #339933;">,</span> T0IF 	<span style="color: #666666; font-style: italic;">; 检测TMR0是否溢出</span>
	<span style="color: #000000; font-weight: bold;">GOTO</span>	<span style="color: #00007f; font-weight: bold;">TEST</span>
	INCF	COUNT<span style="color: #339933;">,</span> F 	<span style="color: #666666; font-style: italic;">; 计数加一</span>
	MOVFF	COUNT<span style="color: #339933;">,</span> PORTD 	<span style="color: #666666; font-style: italic;">; 输出，显示</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">GOTO</span>	<span style="color: #00007f; font-weight: bold;">LOOP</span>
&nbsp;
WIRT_EE				<span style="color: #666666; font-style: italic;">; 写EEPROM</span>
	BCF	EECON1<span style="color: #339933;">,</span> EEPGD
	BCF	EECON1<span style="color: #339933;">,</span> CFGS 	<span style="color: #666666; font-style: italic;">; 设定EECON1控制寄存器</span>
	<span style="color: #00007f; font-weight: bold;">BSF</span>	EECON1<span style="color: #339933;">,</span> WREN 	<span style="color: #666666; font-style: italic;">; EEPROM写使能</span>
	BCF	INTCON<span style="color: #339933;">,</span> GIE 	<span style="color: #666666; font-style: italic;">; 写EEPROM时需要关闭一切中断</span>
&nbsp;
	MOVLW	0x55h 	<span style="color: #666666; font-style: italic;">; </span>
	MOVWF	EECON2
	MOVLW	0xAAh
	MOVWF	EECON2
	<span style="color: #00007f; font-weight: bold;">BSF</span>	EECON1<span style="color: #339933;">,</span> WR 	<span style="color: #666666; font-style: italic;">; 经典的五指令序列，将EEDATA写入EEPROM</span>
&nbsp;
	<span style="color: #00007f; font-weight: bold;">BSF</span>	INTCON<span style="color: #339933;">,</span> GIE 	<span style="color: #666666; font-style: italic;">; 开全局中断</span>
	BCF	EECON1<span style="color: #339933;">,</span> WREN 	<span style="color: #666666; font-style: italic;">; 提前关闭写使能</span>
	RETURN	
&nbsp;
READ_EE				<span style="color: #666666; font-style: italic;">; 读EEPROM</span>
	BCF	EECON1<span style="color: #339933;">,</span> EEPGD
	BCF	EECON1<span style="color: #339933;">,</span> CFGS
	<span style="color: #00007f; font-weight: bold;">BSF</span>	EECON1<span style="color: #339933;">,</span> RD
	<span style="color: #00007f; font-weight: bold;">NOP</span>	
	MOVF	EEDATA<span style="color: #339933;">,</span> W 	<span style="color: #666666; font-style: italic;">; 将读出的结果写入W并返回，</span>
	RETURN	
&nbsp;
&nbsp;
INT0_ISR	
				<span style="color: #666666; font-style: italic;">; 外部中断int0服务程序，可以利用外部电路，</span>
				<span style="color: #666666; font-style: italic;">; 实现掉电时将当前计数值写入EEPROM</span>
	BTFSS	INTCON<span style="color: #339933;">,</span> INT0IF  <span style="color: #666666; font-style: italic;">; 重新测试溢出位，防止干扰信号触发中断</span>
	RETFIE	
	BCF	INTCON<span style="color: #339933;">,</span> INT0IF
	MOVLW	0x00h
	MOVWF	EEADR
	MOVFF	COUNT<span style="color: #339933;">,</span> EEDATA
	<span style="color: #00007f; font-weight: bold;">CALL</span>	WIRT_EE
&nbsp;
	RETFIE			<span style="color: #666666; font-style: italic;">; 中断返回</span>
<span style="color: #000000; font-weight: bold;">END</span></pre></td></tr></table></div>

<p>662e438d</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/pic18-eeprom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PIC18 ADC模数转换</title>
		<link>http://www.dutor.net/index.php/2009/11/pic18f52-adc/</link>
		<comments>http://www.dutor.net/index.php/2009/11/pic18f52-adc/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 14:40:37 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[尚未分类]]></category>
		<category><![CDATA[单片机]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1700</guid>
		<description><![CDATA[　　使用PIC18单片机的ADC转换模块对RA0口输入的模拟电压信号进行转换，然后通过PORTD端口输出，而这里与PORTD对应引脚相连接的是8个LED。
<pre lang="asm" line="1">
list P = 18F452 ;指明单片机型号为PIC18F452
#include P18F452.INC ;包含一个头文件，其中定义了一些端口及一些特殊寄存器的地址

	org	0000h  	;PIC上电时从0000h单元开始执行
	goto	main  	;跳转到主程序
	ORG	0008H  	;中断向量入口
	BTFSS	PIR1, ADIF 	; AD转换完成中断
	RETFIE
	GOTO	AD_ISR

	ORG	0030H  	;主程序定位
MAIN
	CLRF	TRISD  	;设定D口方向为输出
	CLRF 	PORTD 	;设定C口方向为输出
	BSF 	TRISA, 0 	; 使用AN0输入
	MOVLW	81H 	;FOSC/32, AN0, 开启
	MOVWF	ADCON0
	MOVLW	0EH 	;左对齐,AN0为模拟输入
	MOVWF	ADCON1 	;VDD &#038; VSS为参考电压
	BCF 	INTCON, TMR0IF
	BCF 	PIR1, ADIF 	;清AD中断标志位
	BSF 	PIE1, ADIE 	;开AD中断
	BSF 	INTCON, PEIE 	;开外围中断
	BSF  	NTCON, GIE 	;开总中断
	MOVLW 	C7H 	;TMR0 8位，分频比为1:256
	MOVWF	T0CON
LOOP
	CALL	DELAY
	BSF  	DCON0, GO 	;开启 A/D转换
	GOTO	LOOP

DELAY

	BTFSS  	NTCON, TMR0IF 	; 等待延时，采样保持
	GOTO  	DELAY
	BCF  	NTCON, TMR0IF
	RETURN

AD_ISR ;AD转换完成时调用的中断服务程序，将转换结果输出
	ORG 	0200H
	MOVFF	ADRESH, PORTD 	;显示转换结果
	BCF 	PIR1, ADIF 	;清AD中断标志位
	RETFIE
END 	;程序结束
</pre>]]></description>
			<content:encoded><![CDATA[<p>　　使用PIC18单片机的ADC转换模块对RA0口输入的模拟电压信号进行转换，然后通过PORTD端口输出，而这里与PORTD对应引脚相连接的是8个LED。</p>

<div class="wp_codebox"><table><tr id="p17002"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
</pre></td><td class="code" id="p1700code2"><pre class="asm" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">list</span> P = 18F452 <span style="color: #666666; font-style: italic;">;指明单片机型号为PIC18F452</span>
#include P18F452<span style="color: #339933;">.</span><span style="color: #00007f; font-weight: bold;">INC</span> <span style="color: #666666; font-style: italic;">;包含一个头文件，其中定义了一些端口及一些特殊寄存器的地址</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">org</span>	<span style="color: #0000ff;">0000h</span>  	<span style="color: #666666; font-style: italic;">;PIC上电时从0000h单元开始执行</span>
	<span style="color: #000000; font-weight: bold;">goto</span>	main  	<span style="color: #666666; font-style: italic;">;跳转到主程序</span>
	<span style="color: #000000; font-weight: bold;">ORG</span>	<span style="color: #0000ff;">0008H</span>  	<span style="color: #666666; font-style: italic;">;中断向量入口</span>
	BTFSS	PIR1<span style="color: #339933;">,</span> ADIF 	<span style="color: #666666; font-style: italic;">; AD转换完成中断</span>
	RETFIE
	<span style="color: #000000; font-weight: bold;">GOTO</span>	AD_ISR
&nbsp;
	<span style="color: #000000; font-weight: bold;">ORG</span>	<span style="color: #0000ff;">0030H</span>  	<span style="color: #666666; font-style: italic;">;主程序定位</span>
MAIN
	CLRF	TRISD  	<span style="color: #666666; font-style: italic;">;设定D口方向为输出</span>
	CLRF 	PORTD 	<span style="color: #666666; font-style: italic;">;设定C口方向为输出</span>
	<span style="color: #00007f; font-weight: bold;">BSF</span> 	TRISA<span style="color: #339933;">,</span> <span style="color: #0000ff;">0</span> 	<span style="color: #666666; font-style: italic;">; 使用AN0输入</span>
	MOVLW	<span style="color: #0000ff;">81H</span> 	<span style="color: #666666; font-style: italic;">;FOSC/32, AN0, 开启</span>
	MOVWF	ADCON0
	MOVLW	<span style="color: #0000ff;">0EH</span> 	<span style="color: #666666; font-style: italic;">;左对齐,AN0为模拟输入</span>
	MOVWF	ADCON1 	<span style="color: #666666; font-style: italic;">;VDD &amp; VSS为参考电压</span>
	BCF 	INTCON<span style="color: #339933;">,</span> TMR0IF
	BCF 	PIR1<span style="color: #339933;">,</span> ADIF 	<span style="color: #666666; font-style: italic;">;清AD中断标志位</span>
	<span style="color: #00007f; font-weight: bold;">BSF</span> 	PIE1<span style="color: #339933;">,</span> ADIE 	<span style="color: #666666; font-style: italic;">;开AD中断</span>
	<span style="color: #00007f; font-weight: bold;">BSF</span> 	INTCON<span style="color: #339933;">,</span> PEIE 	<span style="color: #666666; font-style: italic;">;开外围中断</span>
	<span style="color: #00007f; font-weight: bold;">BSF</span>  	NTCON<span style="color: #339933;">,</span> GIE 	<span style="color: #666666; font-style: italic;">;开总中断</span>
	MOVLW 	C7H 	<span style="color: #666666; font-style: italic;">;TMR0 8位，分频比为1:256</span>
	MOVWF	T0CON
<span style="color: #00007f; font-weight: bold;">LOOP</span>
	<span style="color: #00007f; font-weight: bold;">CALL</span>	DELAY
	<span style="color: #00007f; font-weight: bold;">BSF</span>  	DCON0<span style="color: #339933;">,</span> GO 	<span style="color: #666666; font-style: italic;">;开启 A/D转换</span>
	<span style="color: #000000; font-weight: bold;">GOTO</span>	<span style="color: #00007f; font-weight: bold;">LOOP</span>
&nbsp;
DELAY
&nbsp;
	BTFSS  	NTCON<span style="color: #339933;">,</span> TMR0IF 	<span style="color: #666666; font-style: italic;">; 等待延时，采样保持</span>
	<span style="color: #000000; font-weight: bold;">GOTO</span>  	DELAY
	BCF  	NTCON<span style="color: #339933;">,</span> TMR0IF
	RETURN
&nbsp;
AD_ISR <span style="color: #666666; font-style: italic;">;AD转换完成时调用的中断服务程序，将转换结果输出</span>
	<span style="color: #000000; font-weight: bold;">ORG</span> 	<span style="color: #0000ff;">0200H</span>
	MOVFF	ADRESH<span style="color: #339933;">,</span> PORTD 	<span style="color: #666666; font-style: italic;">;显示转换结果</span>
	BCF 	PIR1<span style="color: #339933;">,</span> ADIF 	<span style="color: #666666; font-style: italic;">;清AD中断标志位</span>
	RETFIE
<span style="color: #000000; font-weight: bold;">END</span> 	<span style="color: #666666; font-style: italic;">;程序结束</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/pic18f52-adc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>内存泄漏小陷阱</title>
		<link>http://www.dutor.net/index.php/2009/11/mem-leak-trap/</link>
		<comments>http://www.dutor.net/index.php/2009/11/mem-leak-trap/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 04:36:20 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[字符串]]></category>
		<category><![CDATA[汇编]]></category>
		<category><![CDATA[虚拟内存]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1681</guid>
		<description><![CDATA[<pre lang="cpp" line="1">
int
main()
{
	char * str = new char[32];
	str = "Hello, Piggy!";
	return 0;
}
</pre>
这样是会内存泄漏的……而我一直都不知道……不过想来也自然，因为这样是允许的，char *str = "Hello, Piggy!";，“程序中的字符串被存放在常量存储区”不要把这句话当成耳旁风，谨记。]]></description>
			<content:encoded><![CDATA[
<div class="wp_codebox"><table><tr id="p16813"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p1681code3"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> str <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">char</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">32</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
	str <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;Hello, Piggy!&quot;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>这样是会内存泄漏的……而我一直都不知道……</p>

<div class="wp_codebox"><table><tr id="p16814"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1681code4"><pre class="asm" style="font-family:monospace;"><span style="color: #339933;">.</span>LC0<span style="color: #339933;">:</span>
	<span style="color: #339933;">.</span>string	<span style="color: #7f007f;">&quot;Hello, Piggy!&quot;</span>
	<span style="color: #339933;">.</span>text
<span style="color: #339933;">.</span>globl main
	<span style="color: #339933;">.</span><span style="color: #000000; font-weight: bold;">type</span>	main<span style="color: #339933;">,</span> @function
main<span style="color: #339933;">:</span>
	andl	$<span style="color: #339933;">-</span><span style="color: #0000ff;">16</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	subl	$<span style="color: #0000ff;">32</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	movl	$<span style="color: #0000ff;">32</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">call</span>	_Znaj
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">28</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #339933;">.</span>LC0<span style="color: #339933;">,</span> <span style="color: #0000ff;">28</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">;把str给覆盖了</span></pre></td></tr></table></div>

<p>不过想来也自然，因为这样是允许的，char *str = &#8220;Hello, Piggy!&#8221;;，“程序中的字符串被存放在常量存储区”不要把这句话当成耳旁风，谨记。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/mem-leak-trap/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>sizeof只是个运算符</title>
		<link>http://www.dutor.net/index.php/2009/11/sizeof-just-operator/</link>
		<comments>http://www.dutor.net/index.php/2009/11/sizeof-just-operator/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 04:35:05 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1595</guid>
		<description><![CDATA[　　有的东西，你自己觉得自己理解了知道了记住了，可能你真的记住了，但你真的理解了吗？Put a "Why" upon everything ever you touch. 
　　sizeof仅仅是个运算符，但那又意味着什么呢？意味着它不是一个函数，意味着它是在编译期求值(我并不是说所有的运算符都编译期求值)的。对于这样一条语句：
<pre lang="cpp" line="1">size_t size = sizeof(int);</pre>
来说，仅仅对应着这样一条汇编指令：
<pre lang="asm" line="1">movl	$4, -4(%ebp) </pre>
　　这对于自定义类型class也是同样的。]]></description>
			<content:encoded><![CDATA[<p>　　有的东西，你自己觉得自己理解了知道了记住了，可能你真的记住了，但你真的理解了吗？Put a &#8220;Why&#8221; upon everything ever you touch.<br />
　　sizeof仅仅是个运算符，但那又意味着什么呢？意味着它不是一个函数，意味着它是在编译期求值(我并不是说所有的运算符都编译期求值)的。对于这样一条语句：</p>

<div class="wp_codebox"><table><tr id="p15955"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1595code5"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">size_t</span> size <span style="color: #000080;">=</span> <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>来说，仅仅对应着这样一条汇编指令：</p>

<div class="wp_codebox"><table><tr id="p15956"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1595code6"><pre class="asm" style="font-family:monospace;">movl	$<span style="color: #0000ff;">4</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span></pre></td></tr></table></div>

<p>　　这对于自定义类型class也是同样的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/sizeof-just-operator/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PIC中断汇编</title>
		<link>http://www.dutor.net/index.php/2009/11/pic-int-asm/</link>
		<comments>http://www.dutor.net/index.php/2009/11/pic-int-asm/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 23:24:20 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[尚未分类]]></category>
		<category><![CDATA[单片机]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1580</guid>
		<description><![CDATA[　　PIC的汇编实在诡异，有点被颠覆的感觉，原来汇编指令还可以这么来设计，原来汇编指令怎么设计都可以。最OOXX的一条指令就一个实现短转移的指令叫做BRA，意为BRAanch，看到这条指令的时候，我都诧异了，奶罩能做什么？哇塞！居然还能跳转！？奶罩居然可以无条件跳转？！Orz……另外PIC指令把单词缩写运用的淋漓尽致，譬如指令BTFSS，是一条位测试加条件跳转指令：BTFSS = Bit + Test + FileRegister + Skip + Set，用法：BTFSS  R1, 0003h, 寄存器R1的第3位为1时跳过<strong>下一条指令</strong>。真是震撼！

　　最后附上PIC18的中断体系硬件结构图，出自陈育斌老师的手笔：]]></description>
			<content:encoded><![CDATA[
<div class="wp_codebox"><table><tr id="p15807"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
</pre></td><td class="code" id="p1580code7"><pre class="asm" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">list</span> P = 18F452
#include P18F452<span style="color: #339933;">.</span><span style="color: #00007f; font-weight: bold;">INC</span>
&nbsp;
MOVLF <span style="color: #000000; font-weight: bold;">macro</span> R<span style="color: #339933;">,</span> K
    movlw 	K
    movwf 	R
<span style="color: #000000; font-weight: bold;">endm</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">; 定义了几个寄存器</span>
    R1  	EQU <span style="color: #0000ff;">20H</span>
    R2  	EQU <span style="color: #0000ff;">21H</span>
    R3  	EQU <span style="color: #0000ff;">22H</span>
    R4 		EQU <span style="color: #0000ff;">23H</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">ORG</span> 	<span style="color: #0000ff;">0008H</span>  <span style="color: #666666; font-style: italic;">;中断向量入口</span>
    <span style="color: #000000; font-weight: bold;">GOTO</span> 	SELECT <span style="color: #666666; font-style: italic;">;跳转到中段服务选择子程序</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">org</span>		<span style="color: #0000ff;">0000h</span>  <span style="color: #666666; font-style: italic;">;PIC上电时从0000h单元开始执行</span>
	<span style="color: #000000; font-weight: bold;">goto</span>	main  <span style="color: #666666; font-style: italic;">;跳转到主程序</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">org</span>		<span style="color: #0000ff;">0030h</span>  <span style="color: #666666; font-style: italic;">;主程序定位</span>
main
	clrf	TRISD  <span style="color: #666666; font-style: italic;">;设定D口方向为输出</span>
    CLRF	TRISC <span style="color: #666666; font-style: italic;">;设定C口方向为输出</span>
    CLRF	PORTC <span style="color: #666666; font-style: italic;">;C口置零</span>
    <span style="color: #00007f; font-weight: bold;">BSF</span> 	TRISB<span style="color: #339933;">,</span> INT0 <span style="color: #666666; font-style: italic;">; 设定int0中断源对应引脚为输入</span>
    CLRF 	PORTD
    CLRF	INTCON <span style="color: #666666; font-style: italic;">;先将中断控制寄存器清零</span>
    <span style="color: #00007f; font-weight: bold;">BSF</span> 	INTCON<span style="color: #339933;">,</span> GIE <span style="color: #666666; font-style: italic;">; 允许全局中断</span>
    <span style="color: #00007f; font-weight: bold;">BSF</span>  	INTCON<span style="color: #339933;">,</span> TMR0IE <span style="color: #666666; font-style: italic;">; 允许TMR0定时器中断</span>
    <span style="color: #00007f; font-weight: bold;">BSF</span>		INTCON<span style="color: #339933;">,</span> INT0IE <span style="color: #666666; font-style: italic;">; 允许int0中断</span>
    MOVLF  	T0CON<span style="color: #339933;">,</span> <span style="color: #0000ff;">07H</span> <span style="color: #666666; font-style: italic;">; 设定定时器0的计数模式</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">; 给定时器装入初值，定时器为特殊的双缓冲结构，</span>
    <span style="color: #666666; font-style: italic;">; 注意初值的装入顺序为先高后低</span>
    MOVLF 	TMR0H<span style="color: #339933;">,</span> <span style="color: #0000ff;">0C2H</span>
    MOVLF  	TMR0L<span style="color: #339933;">,</span> <span style="color: #0000ff;">0F7H</span>
    <span style="color: #00007f; font-weight: bold;">BSF</span>  	T0CON<span style="color: #339933;">,</span> TMR0ON <span style="color: #666666; font-style: italic;">; 打开定时器开始计数</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">LOOP</span> <span style="color: #666666; font-style: italic;">; PIC汇编的标号不需要冒号':'</span>
   	<span style="color: #666666; font-style: italic;">;SLEEP  ; 进入Sleep模式</span>
   	<span style="color: #000000; font-weight: bold;">GOTO</span> <span style="color: #00007f; font-weight: bold;">LOOP</span> <span style="color: #666666; font-style: italic;">; 转啊转</span>
&nbsp;
&nbsp;
SELECT <span style="color: #666666; font-style: italic;">; 中断服务选择程序,这里的测试顺序决定了中断优先级</span>
   	BTFSC   INTCON<span style="color: #339933;">,</span> TMR0IF <span style="color: #666666; font-style: italic;">; 测试定时器溢出位，为0则跳过一条指令</span>
   	<span style="color: #000000; font-weight: bold;">GOTO</span>   	TMR0_ISR <span style="color: #666666; font-style: italic;">; TMR0IF为1时，跳转到定时器服务程序</span>
   	<span style="color: #666666; font-style: italic;">;NOP</span>
   	BTFSS   INTCON<span style="color: #339933;">,</span> INT0IF <span style="color: #666666; font-style: italic;">; 测试外部中断int0的标志位，为0则跳一步</span>
   	RETFIE <span style="color: #666666; font-style: italic;">; 中断返回，会涉及到出栈操作</span>
   	<span style="color: #000000; font-weight: bold;">GOTO</span>   	INT0_ISR <span style="color: #666666; font-style: italic;">; 跳转到int0服务程序</span>
&nbsp;
TMR0_ISR <span style="color: #666666; font-style: italic;">; 定时器服务程序</span>
   	BTFSS   INTCON<span style="color: #339933;">,</span> TMR0IF  <span style="color: #666666; font-style: italic;">; 重新测试溢出位，防止干扰信号触发中断</span>
   	RETFIE
   	BCF  	INTCON<span style="color: #339933;">,</span> TMR0IF  <span style="color: #666666; font-style: italic;">; 清除溢出位</span>
   	<span style="color: #666666; font-style: italic;">;BSF  	INTCON, GIE ; </span>
   	INCF   	PORTD<span style="color: #339933;">,</span> F <span style="color: #666666; font-style: italic;">; D口加1</span>
   	MOVLF 	TMR0H<span style="color: #339933;">,</span> <span style="color: #0000ff;">0C2H</span> <span style="color: #666666; font-style: italic;">; 计数器初值进行重装</span>
   	MOVLF  	TMR0L<span style="color: #339933;">,</span> <span style="color: #0000ff;">0F7H</span>
&nbsp;
   	RETFIE <span style="color: #666666; font-style: italic;">; 中断返回</span>
&nbsp;
&nbsp;
INT0_ISR <span style="color: #666666; font-style: italic;">; 外部中断int0服务程序</span>
   	<span style="color: #666666; font-style: italic;">;CALL 	delay</span>
   	BTFSS   INTCON<span style="color: #339933;">,</span> INT0IF  <span style="color: #666666; font-style: italic;">; 重新测试溢出位，防止干扰信号触发中断</span>
   	RETFIE
   	BCF   	INTCON<span style="color: #339933;">,</span> INT0IF <span style="color: #666666; font-style: italic;">; 清除溢出位</span>
   	<span style="color: #666666; font-style: italic;">; 下面的几行通过更改定时器的分频比来改变定时间隔，每次减半</span>
   	MOVFF  	T0CON<span style="color: #339933;">,</span> R1
   	DECF   	R1<span style="color: #339933;">,</span> W
   	ANDWF   <span style="color: #0000ff;">07H</span>
   	MOVWF   T0CON
   	<span style="color: #666666; font-style: italic;">; D口加1</span>
   	INCF   	PORTD
   	<span style="color: #666666; font-style: italic;">;MOVLF  R1, 0005H</span>
   	<span style="color: #666666; font-style: italic;">;MOVF 	PORTD, W</span>
   	<span style="color: #666666; font-style: italic;">;SUBWF 	R1, W</span>
   	<span style="color: #666666; font-style: italic;">;BNZ 	NEXT</span>
   	<span style="color: #666666; font-style: italic;">;BSF 	PORTC, 0002H</span>
   	<span style="color: #666666; font-style: italic;">;CALL 	DELAY</span>
   	<span style="color: #666666; font-style: italic;">;BCF 	PORTC, 0002H</span>
NEXT
&nbsp;
   	RETFIE <span style="color: #666666; font-style: italic;">; 中断返回</span>
&nbsp;
SPEAKER
  	<span style="color: #00007f; font-weight: bold;">BSF</span>  PORTC<span style="color: #339933;">,</span> <span style="color: #0000ff;">0002H</span>
  	RETURN
DELAY  <span style="color: #666666; font-style: italic;">; 软件延时</span>
	movlw	<span style="color: #0000ff;">0xFF</span>
	movwf 	R1
L3
	movlw	<span style="color: #0000ff;">0x1f</span>
	movwf	R2
L2
	movlw	<span style="color: #0000ff;">0x1f</span>
	movwf	R3
L1
	decf	R3<span style="color: #339933;">,</span> F
	bnz		L1
	decf		R2<span style="color: #339933;">,</span> F
	bnz		L2
	decf		R1<span style="color: #339933;">,</span> F
	bnz		L3
	return
&nbsp;
<span style="color: #000000; font-weight: bold;">end</span></pre></td></tr></table></div>

<p>　　PIC的汇编实在诡异，有点被颠覆的感觉，原来汇编指令还可以这么来设计，原来汇编指令怎么设计都可以。最OOXX的一条指令就一个实现短转移的指令叫做BRA，意为BRAanch，看到这条指令的时候，我都诧异了，奶罩能做什么？哇塞！居然还能跳转！？奶罩居然可以无条件跳转？！Orz……另外PIC指令把单词缩写运用的淋漓尽致，譬如指令BTFSS，是一条位测试加条件跳转指令：BTFSS = Bit + Test + FileRegister + Skip + Set，用法：BTFSS  R1, 0003h, 寄存器R1的第3位为1时跳过<strong>下一条指令</strong>。真是震撼！</p>
<p>　　最后附上PIC18的中断体系硬件结构图，出自陈育斌老师的手笔：<br />
<div class="wp-caption aligncenter" style="width: 630px"><img alt="PIC18中断体系硬件结构示意图" src="http://www.dutor.net/files/images/pic_int.png" title="PIC18中断体系硬件结构示意图" width="620" height="450" /><p class="wp-caption-text">PIC18中断体系硬件结构示意图</p></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/pic-int-asm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一段小程序</title>
		<link>http://www.dutor.net/index.php/2009/11/snippets/</link>
		<comments>http://www.dutor.net/index.php/2009/11/snippets/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 04:40:13 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1562</guid>
		<description><![CDATA[　　这里面猫腻儿还真不少。

　　karmic到源里面没有以前到vim-full包了，取而代之到是vim包，但现在有很多问题，n"+yy和n"+p无法和系统"剪切板"里到内容关联了，不知道什么原因。

<strong>Update</strong>
　　一切都释然了，只要意识到，>也需要进行类型提升。那么后面到-1啦-2啦之类的，都是很大很大的数了，循环根本就进不去，更别提死循环了。这样看来<strong>四、五</strong>两段程序就没有必要列出来了。其实，我是被它们的汇编代码给迷惑住了。]]></description>
			<content:encoded><![CDATA[<p><strong>一、</strong><br />
源程序，</p>

<div class="wp_codebox"><table><tr id="p15628"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p1562code8"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">unsigned</span> a <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">int</span> b <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>a <span style="color: #000040;">+</span> b <span style="color: #000080;">&gt;=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">--</span>b<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>汇编后，</p>

<div class="wp_codebox"><table><tr id="p15629"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p1562code9"><pre class="asm" style="font-family:monospace;">	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #339933;">.</span>L2<span style="color: #339933;">:</span>
	subl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span>	<span style="color: #339933;">.</span>L2</pre></td></tr></table></div>

<p><strong>二、</strong><br />
源程序，</p>

<div class="wp_codebox"><table><tr id="p156210"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1562code10"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">//...</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>a <span style="color: #000040;">+</span> b <span style="color: #000080;">&gt;</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">--</span>b<span style="color: #008080;">;</span>
<span style="color: #666666;">//...</span></pre></td></tr></table></div>

<p>汇编后，</p>

<div class="wp_codebox"><table><tr id="p156211"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1562code11"><pre class="asm" style="font-family:monospace;">	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span>	<span style="color: #339933;">.</span>L2
<span style="color: #339933;">.</span>L3<span style="color: #339933;">:</span>
	subl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #339933;">.</span>L2<span style="color: #339933;">:</span>
	movl	<span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	addl	<span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	testl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">setne</span>	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	testb	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	<span style="color: #00007f; font-weight: bold;">jne</span>	<span style="color: #339933;">.</span>L3</pre></td></tr></table></div>

<p><strong>三、</strong><br />
源程序，</p>

<div class="wp_codebox"><table><tr id="p156212"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1562code12"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">//...</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>a <span style="color: #000040;">+</span> b <span style="color: #000080;">&gt;</span> <span style="color: #000040;">-</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">--</span>b<span style="color: #008080;">;</span>
<span style="color: #666666;">//...</span></pre></td></tr></table></div>

<p>汇编后，</p>

<div class="wp_codebox"><table><tr id="p156213"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1562code13"><pre class="asm" style="font-family:monospace;">	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span>	<span style="color: #339933;">.</span>L2
<span style="color: #339933;">.</span>L3<span style="color: #339933;">:</span>
	subl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #339933;">.</span>L2<span style="color: #339933;">:</span>
	movl	<span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	addl	<span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	cmpl	$<span style="color: #339933;">-</span><span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">sete</span>	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	testb	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	<span style="color: #00007f; font-weight: bold;">jne</span>	<span style="color: #339933;">.</span>L3</pre></td></tr></table></div>

<p><strong>四、</strong><br />
源程序，</p>

<div class="wp_codebox"><table><tr id="p156214"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1562code14"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">//...</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>a <span style="color: #000040;">+</span> b <span style="color: #000080;">&gt;=</span> <span style="color: #000040;">-</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">--</span>b<span style="color: #008080;">;</span>
<span style="color: #666666;">//...</span></pre></td></tr></table></div>

<p>汇编后，</p>

<div class="wp_codebox"><table><tr id="p156215"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1562code15"><pre class="asm" style="font-family:monospace;">	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span>	<span style="color: #339933;">.</span>L2
<span style="color: #339933;">.</span>L3<span style="color: #339933;">:</span>
	subl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #339933;">.</span>L2<span style="color: #339933;">:</span>
	movl	<span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	addl	<span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	cmpl	$<span style="color: #339933;">-</span><span style="color: #0000ff;">3</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">seta</span>	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	testb	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	<span style="color: #00007f; font-weight: bold;">jne</span>	<span style="color: #339933;">.</span>L3</pre></td></tr></table></div>

<p><strong>五、</strong><br />
源代码，</p>

<div class="wp_codebox"><table><tr id="p156216"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1562code16"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">//...</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>a <span style="color: #000040;">+</span> b <span style="color: #000080;">&gt;=</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">--</span>b<span style="color: #008080;">;</span>
<span style="color: #666666;">//...</span></pre></td></tr></table></div>

<p>汇编后，</p>

<div class="wp_codebox"><table><tr id="p156217"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1562code17"><pre class="asm" style="font-family:monospace;">	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span>	<span style="color: #339933;">.</span>L2
<span style="color: #339933;">.</span>L3<span style="color: #339933;">:</span>
	subl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #339933;">.</span>L2<span style="color: #339933;">:</span>
	movl	<span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	addl	<span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	testl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">setne</span>	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	testb	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	<span style="color: #00007f; font-weight: bold;">jne</span>	<span style="color: #339933;">.</span>L3</pre></td></tr></table></div>

<p>　　<br />
　　这里面猫腻儿还真不少。</p>
<p>　　karmic到源里面没有以前到vim-full包了，取而代之到是vim包，但现在有很多问题，n&#8221;+yy和n&#8221;+p无法和系统&#8221;剪切板&#8221;里到内容关联了，不知道什么原因。</p>
<p><strong>Update</strong><br />
　　一切都释然了，只要意识到，>也需要进行类型提升。那么后面到-1啦-2啦之类的，都是很大很大的数了，循环根本就进不去，更别提死循环了。这样看来<strong>四、五</strong>两段程序就没有必要列出来了。其实，我是被它们的汇编代码给迷惑住了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/snippets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>最小的程序</title>
		<link>http://www.dutor.net/index.php/2009/09/short-elf/</link>
		<comments>http://www.dutor.net/index.php/2009/09/short-elf/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 14:25:11 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[Unix/Linux]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[OS基础]]></category>
		<category><![CDATA[动态链接]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1248</guid>
		<description><![CDATA[　　这里面没有用到C库，也没有main函数，为了把这个程序编译成可执行文件，需要指定程序的入口。编译指令：
<pre lang="bash" line="1">
$ gcc -c nomain.c 
$ ld -e nomain nomain.o -o nomain
$ ./nomain
$ echo $?
42
$ ls -l nomain
-rwxr-xr-x 1 ivan ivan 618 2009-09-02 22:11 nomain
$ strip nomain
$ ls -l nomain
-rwxr-xr-x 1 ivan ivan 356 2009-09-02 22:15 nomain
</pre>

　　解释一下，ld是linux下的一个链接器，-e选项用来指定程序的入口。编译后可执行文件的大小为618字节(一个动态链接的HelloWorld需要9KB，静态链接将近600K)，strip命令可以"剥去"可执行文件中的调试信息，可进一步减小文件的大小，另外在链接时通过其他选项还可以将可执行文件中保存的编译器和系统版本信息也一并去掉……]]></description>
			<content:encoded><![CDATA[
<div class="wp_codebox"><table><tr id="p124818"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p1248code18"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span>
nomain<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    asm<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;movl $42, %ebx <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>&quot;</span>
            <span style="color: #FF0000;">&quot;movl $1, %eax <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>&quot;</span>
            <span style="color: #FF0000;">&quot;int $0x80 <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　程序中使用了EXIT系统调用，Linux中是通过0&#215;80号中断实现的，寄存器ebx表示进程退出码，比如我们平时的main程序中的return的数值会返回系统库，由系统库将该数值传递给EXIT系统调用。这样父进程就能接受到子进程的退出码，例如在bash中环境变量$?就保存了上一个命令(即子进程)的退出码。寄存器eax用来保存系统调用的调用号，例如EXIT系统调用的调用号是1，write系统调用号为4。因此这个小程序的功能就是直接返回至父进程。</p>
<p>　　这里面没有用到C库，也没有main函数，为了把这个程序编译成可执行文件，需要指定程序的入口。编译指令：</p>

<div class="wp_codebox"><table><tr id="p124819"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p1248code19"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">gcc</span> <span style="color: #660033;">-c</span> nomain.c 
$ <span style="color: #c20cb9; font-weight: bold;">ld</span> <span style="color: #660033;">-e</span> nomain nomain.o <span style="color: #660033;">-o</span> nomain
$ .<span style="color: #000000; font-weight: bold;">/</span>nomain
$ <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$?</span>
<span style="color: #000000;">42</span>
$ <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-l</span> nomain
<span style="color: #660033;">-rwxr-xr-x</span> <span style="color: #000000;">1</span> ivan ivan <span style="color: #000000;">618</span> <span style="color: #000000;">2009</span>-09-02 <span style="color: #000000;">22</span>:<span style="color: #000000;">11</span> nomain
$ <span style="color: #c20cb9; font-weight: bold;">strip</span> nomain
$ <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-l</span> nomain
<span style="color: #660033;">-rwxr-xr-x</span> <span style="color: #000000;">1</span> ivan ivan <span style="color: #000000;">356</span> <span style="color: #000000;">2009</span>-09-02 <span style="color: #000000;">22</span>:<span style="color: #000000;">15</span> nomain</pre></td></tr></table></div>

<p>　　解释一下，ld是linux下的一个链接器，-e选项用来指定程序的入口。编译后可执行文件的大小为618字节(一个动态链接的HelloWorld需要9KB，静态链接将近600K)，strip命令可以&#8221;剥去&#8221;可执行文件中的调试信息，可进一步减小文件的大小，另外在链接时通过其他选项还可以将可执行文件中保存的编译器和系统版本信息也一并去掉……</p>
<p>　　此程序虽已经很小，没有调用任何C库，但还是脱离不了操作系统而独立运行。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/09/short-elf/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Linux动态链接的实现方式</title>
		<link>http://www.dutor.net/index.php/2009/08/linux-dynamic-link-imp/</link>
		<comments>http://www.dutor.net/index.php/2009/08/linux-dynamic-link-imp/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 04:28:46 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[Unix/Linux]]></category>
		<category><![CDATA[OS基础]]></category>
		<category><![CDATA[动态链接]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1182</guid>
		<description><![CDATA[<pre>
0x4000a963 <_dl_runtime_resolve+3>:     movl   0x10(%esp,1),%edx
0x4000a967 <_dl_runtime_resolve+7>:     movl   0xc(%esp,1),%eax
0x4000a96b <_dl_runtime_resolve+11>:    call   0x4000a740 <fixup>
</pre>

　　指令xchgl  %eax,(%esp,1)将printf的地址放入栈顶。最精彩的一条指令当属ret    $0x8，它将栈顶元素即printf的地址弹出至程序计数器PC，作为下一条将执行的指令地址，同时，清除堆栈中的0x10和0x8049560。此时堆栈中的情形，就如同直接调用了printf函数，似乎什么都没发生过。

　　此外<fixup>还做了一件重要的工作，就是把前面提到的addr2替换为printf的地址。从而当再次调用printf时jmp  *addr1就直接将程序定位到printf，不需要再次加载库libc.so了。

　　不知道我说清楚了没有，感觉说的很乱，文字也很乱。:-)]]></description>
			<content:encoded><![CDATA[<p>　　看了一个很牛B的帖子，关于动态链接的：<br />
<a href="http://www.ibm.com/developerworks/cn/linux/l-dynlink/index.html" target="_blank">http://www.ibm.com/developerworks/cn/linux/l-dynlink/index.html</a>。<br />
　　对Linux中C程序的动态链接过程，在这里对几个关键点做一下注解。<br />
　　反汇编后的汇编代码中，调用printf是通过call指令来实现的：</p>
<pre>
 804838c:       e8 47 ff ff ff          call   80482d8
<printf@plt>
 8048391:       b8 00 00 00 00          mov    $0x0,%eax
</pre>
<p>　　其中，0x80482d8是printf在plt中的地址(逻辑地址)。plt是结构这样的：</p>
<pre>
Disassembly of section .plt:

080482a8 <__gmon_start__@plt-0x10>:
 80482a8:       ff 35 60 95 04 08       pushl  0x8049560
 80482ae:       ff 25 64 95 04 08       jmp    *0x8049564
 80482b4:       00 00                   add    %al,(%eax)
080482b8 <__gmon_start__@plt>:
 80482b8:       ff 25 68 95 04 08       jmp    *0x8049568
 80482be:       68 00 00 00 00          push   $0x0
 80482c3:       e9 e0 ff ff ff          jmp    80482a8 <_init+0x30>
080482c8 <__libc_start_main@plt>:
 80482c8:       ff 25 6c 95 04 08       jmp    *0x804956c
 80482ce:       68 08 00 00 00          push   $0x8
 80482d3:       e9 d0 ff ff ff          jmp    80482a8 <_init+0x30>
080482d8 < printf @ plt>:
 80482d8:       ff 25 70 95 04 08       jmp    *0x8049570
 80482de:       68 10 00 00 00          push   $0x10
 80482e3:       e9 c0 ff ff ff          jmp    80482a8 <_init+0x30>
</pre>
<p>　　在call指令执行后执行</p>

<div class="wp_codebox"><table><tr id="p118220"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1182code20"><pre class="bash" style="font-family:monospace;">jmp    <span style="color: #000000; font-weight: bold;">*</span>0x8049570</pre></td></tr></table></div>

<p>　　程序跳转到地址(addr1)0&#215;8049570存储的地址(addr2)处，即*addr1 == addr2，若包含printf的库libc.so尚未加载，这时addr2的值就是0x080482de，即指令push   $0&#215;10。将0&#215;10压入堆栈，用来定位printf在libc.so的位置。接下来的jmp指令将程序定位在0x80482a8，即<__gmon_start__@plt-0x10>处，将0&#215;8049560压入堆栈。jmp    *0&#215;8049564指令是程序跳转到一个固定的加载程序处，即原帖中的function _dl_runtime_resolve：</p>
<pre>
Dump of assembler code for function _dl_runtime_resolve:
0x4000a960 <_dl_runtime_resolve>:       pushl  %eax
0x4000a961 <_dl_runtime_resolve+1>:     pushl  %ecx
0x4000a962 <_dl_runtime_resolve+2>:     pushl  %edx
0x4000a963 <_dl_runtime_resolve+3>:     movl   0x10(%esp,1),%edx
0x4000a967 <_dl_runtime_resolve+7>:     movl   0xc(%esp,1),%eax
0x4000a96b <_dl_runtime_resolve+11>:    call   0x4000a740 <fixup>
0x4000a970 <_dl_runtime_resolve+16>:    popl   %edx
0x4000a971 <_dl_runtime_resolve+17>:    popl   %ecx
0x4000a972 <_dl_runtime_resolve+18>:    xchgl  %eax,(%esp,1)
0x4000a975 <_dl_runtime_resolve+21>:    ret    $0x8
0x4000a978 <_dl_runtime_resolve+24>:    nop
0x4000a979 <_dl_runtime_resolve+25>:    leal   0x0(%esi,1),%esi
End of assembler dump.
</pre>
<p>　　此时的堆栈情况见原帖。以下三条指令，将0&#215;10和0&#215;8049560作为参数放入寄存器edx、eax并调用<fixup>，<fixup>用这两个参数定位并装入printf所在的库libc.so，并将printf的地址放入寄存器eax:</p>
<pre>
0x4000a963 <_dl_runtime_resolve+3>:     movl   0x10(%esp,1),%edx
0x4000a967 <_dl_runtime_resolve+7>:     movl   0xc(%esp,1),%eax
0x4000a96b <_dl_runtime_resolve+11>:    call   0x4000a740 <fixup>
</pre>
<p>　　指令xchgl  %eax,(%esp,1)将printf的地址放入栈顶。最精彩的一条指令当属ret    $0&#215;8，它将栈顶元素即printf的地址弹出至程序计数器PC，作为下一条将执行的指令地址，同时，清除堆栈中的0&#215;10和0&#215;8049560。此时堆栈中的情形，就如同直接调用了printf函数，似乎什么都没发生过。</p>
<p>　　此外<fixup>还做了一件重要的工作，就是把前面提到的addr2替换为printf的地址。从而当再次调用printf时jmp  *addr1就直接将程序定位到printf，不需要再次加载库libc.so了。</p>
<p>　　不知道我说清楚了没有，感觉说的很乱，文字也很乱。:-)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/08/linux-dynamic-link-imp/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>if/else vs ?:</title>
		<link>http://www.dutor.net/index.php/2009/08/if-else-vs-ternary-operator/</link>
		<comments>http://www.dutor.net/index.php/2009/08/if-else-vs-ternary-operator/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 04:55:13 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[汇编]]></category>
		<category><![CDATA[运算符]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1118</guid>
		<description><![CDATA[<pre lang="asm" line="1">
	call ___main
	movl $1,-4(%ebp) ; a
	movl $2,-8(%ebp) ; b
	movl -4(%ebp),%eax ;if/else开始
	cmpl -8(%ebp),%eax
	jge L2
	movl -4(%ebp),%eax
	movl %eax,-12(%ebp)
	jmp L3
	.p2align 4,,7
L2:
	movl -8(%ebp),%eax
	movl %eax,-12(%ebp) ; if/else结束
L3:
	movl -8(%ebp),%eax ; ? :开始
	cmpl -4(%ebp),%eax
	jle L4
	movl -4(%ebp),%eax
L4:
	movl %eax,-12(%ebp) ; ? :结束
</pre>
if/else用了8条指令，?:用了5条，这个差距可不算小了啊！因为，程序里面是要有循环的，多数循环里面会有分支语句，且很多情况下是二分支。
呃……又学到一个单词，ternary：三元。:-)]]></description>
			<content:encoded><![CDATA[<p>听到有人说，if/else比三目运算符? :容易调试，而且可读性高、效率也高( ⊙o⊙ )?！我迅速地搜索?:还有没有存在的理由，难道我一直都在写着晦涩、低效的? : !？为了一探究竟，我写下了这段代码：</p>

<div class="wp_codebox"><table><tr id="p111821"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1118code21"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;stdio.h&gt;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">int</span> a <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span>, b <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span>, c<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>a <span style="color: #000080;">&lt;</span> b<span style="color: #008000;">&#41;</span>
		c <span style="color: #000080;">=</span> a<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">else</span>
		c <span style="color: #000080;">=</span> b<span style="color: #008080;">;</span>
	c <span style="color: #000080;">=</span> a <span style="color: #000080;">&lt;</span> b <span style="color: #008080;">?</span> a <span style="color: #008080;">:</span> b<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>g++ test.cpp -S 得到：</p>

<div class="wp_codebox"><table><tr id="p111822"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p1118code22"><pre class="asm" style="font-family:monospace;">	<span style="color: #00007f; font-weight: bold;">call</span> ___main
	movl $<span style="color: #0000ff;">1</span><span style="color: #339933;">,-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">; a</span>
	movl $<span style="color: #0000ff;">2</span><span style="color: #339933;">,-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">; b</span>
	movl <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">;if/else开始</span>
	cmpl <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">jge</span> L2
	movl <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span>
	movl <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,-</span><span style="color: #0000ff;">12</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span> L3
	<span style="color: #339933;">.</span>p2align <span style="color: #0000ff;">4</span><span style="color: #339933;">,,</span><span style="color: #0000ff;">7</span>
L2<span style="color: #339933;">:</span>
	movl <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span>
	movl <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,-</span><span style="color: #0000ff;">12</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">; if/else结束</span>
L3<span style="color: #339933;">:</span>
	movl <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; ? :开始</span>
	cmpl <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">jle</span> L4
	movl <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span>
L4<span style="color: #339933;">:</span>
	movl <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,-</span><span style="color: #0000ff;">12</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">; ? :结束</span></pre></td></tr></table></div>

<p>if/else用了8条指令，?:用了5条，这个差距可不算小了啊！因为，程序里面是要有循环的，多数循环里面会有分支语句，且很多情况下是二分支。<br />
呃……又学到一个单词，ternary：三元。:-)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/08/if-else-vs-ternary-operator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分析一个奇怪的汇编程序</title>
		<link>http://www.dutor.net/index.php/2009/07/queer-asm/</link>
		<comments>http://www.dutor.net/index.php/2009/07/queer-asm/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 08:30:21 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[cpu]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=859</guid>
		<description><![CDATA[没有放在程序结束处，而是放在的代码段的起始位置，更甚，由于程序是从start开始执行的，似乎永远不会执行到这两行，程序也永远不会结束。但是这个程序却能正常结束，而且是由我们的这两行代码来结束执行的。
其中的猫腻就在于短转移指令jmp short s1。jmp指令是用来更改寄存器CS:IP来实现程序的转移的，汇编语言中一般是以标号来指明跳转的目的地址的。对于长转移指令，例如jmp dword ptr ds:[0]，CPU确实是以目标地址的段基址和段内偏移来修改CS:IP的。但是对于短转移来说，却是利用当前IP与目标地址之间的的偏移量来确定的。上例中，执行jmp short s1时，IP指向下一条指令nop，与目标地址s1之间偏移量为10：
<pre>
   CS:IP     机器码             汇编指令(编译器将标号替换了)
0B80:0018 B80000        MOV     AX,0000    ;s1      
0B80:001B CD21          INT     21
0B80:001D B80000        MOV     AX,0000
0B80:0020 EBF6          JMP     0018           ; jmp short s1
0B80:0022 90              NOP
</pre>
]]></description>
			<content:encoded><![CDATA[
<div class="wp_codebox"><table><tr id="p85923"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code" id="p859code23"><pre class="asm" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">assume</span> <span style="color: #00007f;">cs</span><span style="color: #339933;">:</span><span style="color: #000000; font-weight: bold;">code</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">code</span> <span style="color: #000000; font-weight: bold;">segment</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">04c00h</span>
	<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">21h</span>
start<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0</span>
s<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">nop</span>
	<span style="color: #00007f; font-weight: bold;">nop</span>
&nbsp;
	<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">di</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">offset</span> s
	<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">si</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">offset</span> s2
	<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">cs</span><span style="color: #339933;">:</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">si</span><span style="color: #009900; font-weight: bold;">&#93;</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">cs</span><span style="color: #339933;">:</span><span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">di</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>
&nbsp;
s0<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span> <span style="color: #000000; font-weight: bold;">short</span> s
s1<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0</span>
	<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">21h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0</span>
&nbsp;
s2<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span> <span style="color: #000000; font-weight: bold;">short</span> s1
	<span style="color: #00007f; font-weight: bold;">nop</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">code</span> <span style="color: #000000; font-weight: bold;">ends</span>
<span style="color: #000000; font-weight: bold;">end</span> start</pre></td></tr></table></div>

<p>说这个程序奇怪，是因为用来结束程序并返回的两个语句:</p>
<pre>
	mov ax, 04c00h
	int 21h
</pre>
<p>没有放在程序结束处，而是放在的代码段的起始位置，更甚，由于程序是从start开始执行的，似乎永远不会执行到这两行，程序也永远不会结束。但是这个程序却能正常结束，而且是由我们的这两行代码来结束执行的。<br />
其中的猫腻就在于短转移指令jmp short s1。jmp指令是用来更改寄存器CS:IP来实现程序的转移的，汇编语言中一般是以标号来指明跳转的目的地址的。对于长转移指令，例如jmp dword ptr ds:[0]，CPU确实是以目标地址的段基址和段内偏移来修改CS:IP的。但是对于短转移来说，却是利用当前IP与目标地址之间的的偏移量来确定的。上例中，执行jmp short s1时，IP指向下一条指令nop，与目标地址s1之间偏移量为10：</p>
<pre>
   CS:IP     机器码             汇编指令(编译器将标号进行了替换)
0B80:0018 B80000        MOV     AX,0000    ;s1
0B80:001B CD21          INT     21
0B80:001D B80000        MOV     AX,0000
0B80:0020 EBF6          JMP     0018           ; jmp short s1
0B80:0022 90              NOP
</pre>
<p>s1与s2之间的机器指令整好是10个字节，-10(向低地址方向转移)的补码是0xF6h，看汇编指令jmp short s1对应的机器指令EBF6，发现什么了吗？F6就指明了偏移量！<br />
再回到正题，程序中将jmp short s1原封不动地复制到了s处，当程序执行到s处时，向前跳转10个字节，恰好是本文开始提到的那两条用来结束程序的指令！<br />
其实，这个程序没有任何的实际意义，但却能加深我对汇编指令内部机理的理解。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/07/queer-asm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I2C键盘扫描程序</title>
		<link>http://www.dutor.net/index.php/2009/05/i2c-keyboard-scan-procedure/</link>
		<comments>http://www.dutor.net/index.php/2009/05/i2c-keyboard-scan-procedure/#comments</comments>
		<pubDate>Wed, 06 May 2009 14:22:26 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[单片机]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=378</guid>
		<description><![CDATA[<pre lang="asm" line="1">
;#################################################################
;              这是一个键盘扫描程序 
;将得到的健值（01H-10H）在右边两位数码管显示 (data= XX) 
;程序采用中断结构，硬件连接上将INT_KEY信号与P3.2(INT0) 连接；
;普通的I2C通讯程序可以直接利用，为读数据子程序需要加延时
;这是ZLG7290芯片在读数据时有延时，在RDBYT中添加一个20US延时
;#################################################################
SDA		BIT	P1.0
SCL		BIT	P1.1  
WSLA		EQU	070H
RSLA		EQU	071H
DISDA		EQU	20H		;源数据块首地址
DISCON		EQU	08H		;写入数据个数		
DATA_1		EQU	30H		;变量区首地址
;********************************************************
	ORG	8000H 
	LJMP	8100H  
;********************************************************
</pre>]]></description>
			<content:encoded><![CDATA[
<div class="wp_codebox"><table><tr id="p37824"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
</pre></td><td class="code" id="p378code24"><pre class="asm" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">;#################################################################</span>
<span style="color: #666666; font-style: italic;">;              这是一个键盘扫描程序 </span>
<span style="color: #666666; font-style: italic;">;将得到的健值（01H-10H）在右边两位数码管显示 (data= XX) </span>
<span style="color: #666666; font-style: italic;">;程序采用中断结构，硬件连接上将INT_KEY信号与P3.2(INT0) 连接；</span>
<span style="color: #666666; font-style: italic;">;普通的I2C通讯程序可以直接利用，为读数据子程序需要加延时</span>
<span style="color: #666666; font-style: italic;">;这是ZLG7290芯片在读数据时有延时，在RDBYT中添加一个20US延时</span>
<span style="color: #666666; font-style: italic;">;#################################################################</span>
SDA		BIT	P1<span style="color: #339933;">.</span>0
SCL		BIT	P1<span style="color: #339933;">.</span>1  
WSLA		EQU	<span style="color: #0000ff;">070H</span>
RSLA		EQU	<span style="color: #0000ff;">071H</span>
DISDA		EQU	<span style="color: #0000ff;">20H</span>		<span style="color: #666666; font-style: italic;">;源数据块首地址</span>
DISCON		EQU	<span style="color: #0000ff;">08H</span>		<span style="color: #666666; font-style: italic;">;写入数据个数		</span>
DATA_1		EQU	<span style="color: #0000ff;">30H</span>		<span style="color: #666666; font-style: italic;">;变量区首地址</span>
<span style="color: #666666; font-style: italic;">;********************************************************</span>
	<span style="color: #000000; font-weight: bold;">ORG</span>	<span style="color: #0000ff;">8000H</span> 
	<span style="color: #000000; font-weight: bold;">LJMP</span>	<span style="color: #0000ff;">8100H</span>  
<span style="color: #666666; font-style: italic;">;********************************************************</span>
	<span style="color: #000000; font-weight: bold;">ORG</span>	<span style="color: #0000ff;">8003H</span>
	<span style="color: #000000; font-weight: bold;">LJMP</span>	INT_7290
<span style="color: #666666; font-style: italic;">;********************************************************</span>
<span style="color: #666666; font-style: italic;">;            初始化部分					          </span>
<span style="color: #666666; font-style: italic;">;********************************************************</span>
	<span style="color: #000000; font-weight: bold;">ORG</span>	<span style="color: #0000ff;">8100H</span> 
START<span style="color: #339933;">:</span> <span style="color: #00007f; font-weight: bold;">MOV</span>	<span style="color: #00007f;">SP</span><span style="color: #339933;">,</span>#<span style="color: #0000ff;">60H</span>
	CLR	P1<span style="color: #339933;">.</span>7   		<span style="color: #666666; font-style: italic;">;7290复位</span>
	LCALL	DELAY	
	<span style="color: #00007f; font-weight: bold;">SETB</span>	P1<span style="color: #339933;">.</span>7	
	<span style="color: #00007f; font-weight: bold;">SETB</span>	EA 			<span style="color: #666666; font-style: italic;">;开INT0中断</span>
	<span style="color: #00007f; font-weight: bold;">SETB</span>	EX0
	<span style="color: #00007f; font-weight: bold;">SETB</span>	IT0  		<span style="color: #666666; font-style: italic;">;触发极性为下降沿 	</span>
<span style="color: #666666; font-style: italic;">;********************************************************</span>
<span style="color: #666666; font-style: italic;">;           建立变量缓冲区	(30H-37H) 			          </span>
<span style="color: #666666; font-style: italic;">;********************************************************</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	DATA_1<span style="color: #339933;">,</span>  #<span style="color: #0000ff;">13H</span>	<span style="color: #666666; font-style: italic;">;变量缓冲区(显示 data =   )</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	DATA_1<span style="color: #339933;">+</span><span style="color: #0000ff;">1</span><span style="color: #339933;">,</span>#<span style="color: #0000ff;">13H</span>	<span style="color: #666666; font-style: italic;">;注意：</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	DATA_1<span style="color: #339933;">+</span><span style="color: #0000ff;">2</span><span style="color: #339933;">,</span>#<span style="color: #0000ff;">13H</span> 	<span style="color: #666666; font-style: italic;">;变量取值范围0-F</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	DATA_1<span style="color: #339933;">+</span><span style="color: #0000ff;">3</span><span style="color: #339933;">,</span>#<span style="color: #0000ff;">12H</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	DATA_1<span style="color: #339933;">+</span><span style="color: #0000ff;">4</span><span style="color: #339933;">,</span>#<span style="color: #0000ff;">10H</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	DATA_1<span style="color: #339933;">+</span><span style="color: #0000ff;">5</span><span style="color: #339933;">,</span>#<span style="color: #0000ff;">11H</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	DATA_1<span style="color: #339933;">+</span><span style="color: #0000ff;">6</span><span style="color: #339933;">,</span>#<span style="color: #0000ff;">10H</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	DATA_1<span style="color: #339933;">+</span><span style="color: #0000ff;">7</span><span style="color: #339933;">,</span>#<span style="color: #0000ff;">0DH</span>
<span style="color: #666666; font-style: italic;">;********************************************************</span>
<span style="color: #666666; font-style: italic;">;           通过查表建立显示缓冲区（20H-27H）				          </span>
<span style="color: #666666; font-style: italic;">;********************************************************</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	DPTR<span style="color: #339933;">,</span>#LEDSEG 	<span style="color: #666666; font-style: italic;">;开始对变量查表</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R7<span style="color: #339933;">,</span>#DISCON		<span style="color: #666666; font-style: italic;">;写入数据个数	</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R0<span style="color: #339933;">,</span>#DISDA  		<span style="color: #666666; font-style: italic;">;源数据块首地址</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R1<span style="color: #339933;">,</span>#DATA_1
LOOP1<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">MOV</span>	A<span style="color: #339933;">,</span>@R1
	MOVC	A<span style="color: #339933;">,</span>@A<span style="color: #339933;">+</span>DPTR 		<span style="color: #666666; font-style: italic;">;查表得对应的字形码</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	@R0<span style="color: #339933;">,</span>A 			<span style="color: #666666; font-style: italic;">;送显示缓冲区</span>
	<span style="color: #00007f; font-weight: bold;">INC</span>	R1
	<span style="color: #00007f; font-weight: bold;">INC</span>	R0
	DJNZ	R7<span style="color: #339933;">,</span>LOOP1  
<span style="color: #666666; font-style: italic;">;********************************************************</span>
<span style="color: #666666; font-style: italic;">;	向7290B写入数据，以显示&quot;data=  &quot;</span>
<span style="color: #666666; font-style: italic;">;********************************************************</span>
<span style="color: #00007f; font-weight: bold;">LOOP</span><span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">MOV</span>	R7<span style="color: #339933;">,</span>#DISCON
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R2<span style="color: #339933;">,</span>#<span style="color: #0000ff;">10H</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R3<span style="color: #339933;">,</span>#WSLA
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R0<span style="color: #339933;">,</span>#DISDA 
	LCALL	WRNBYT			<span style="color: #666666; font-style: italic;">;调显示子程序</span>
	LCALL	DELAY 			<span style="color: #666666; font-style: italic;">;使显示稳定 </span>
	SJMP	<span style="color: #00007f; font-weight: bold;">LOOP</span> 
<span style="color: #666666; font-style: italic;">;******************************************************************</span>
LEDSEG<span style="color: #339933;">:</span>	<span style="color: #000000; font-weight: bold;">DB</span>	<span style="color: #0000ff;">0FCH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">60H</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0DAH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0F2H</span><span style="color: #339933;">,</span><span style="color: #0000ff;">66H</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0B6H</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0BEH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0E4H</span>	<span style="color: #666666; font-style: italic;">;0-7的字形码</span>
		<span style="color: #000000; font-weight: bold;">DB</span>	<span style="color: #0000ff;">0FEH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0F6H</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0EEH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">3EH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">9CH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">7AH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">9EH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">8EH</span>		<span style="color: #666666; font-style: italic;">;8-F的字形码</span>
		<span style="color: #000000; font-weight: bold;">DB</span>	<span style="color: #0000ff;">0FAH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">1EH</span><span style="color: #339933;">,</span><span style="color: #0000ff;">12H</span><span style="color: #339933;">,</span><span style="color: #0000ff;">00H</span>						<span style="color: #666666; font-style: italic;">;a,t,= 和熄灭码</span>
<span style="color: #666666; font-style: italic;">;******************************************************************</span>
<span style="color: #666666; font-style: italic;">;	拆分程序（将A中的数据拆分为两个四位16进制数并查表）</span>
<span style="color: #666666; font-style: italic;">;	( 结果在R4、R3中 ) </span>
<span style="color: #666666; font-style: italic;">;******************************************************************</span>
CF<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">PUSH</span>	<span style="color: #0000ff;">02H</span> 		<span style="color: #666666; font-style: italic;">;将A中的数据拆分为两个四位16进制数并查表</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span>	DPH  	<span style="color: #666666; font-style: italic;">;	</span>
<span style="color: #00007f; font-weight: bold;">PUSH</span>	DPL
	<span style="color: #00007f; font-weight: bold;">MOV</span>	DPTR<span style="color: #339933;">,</span>#LEDSEG
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R2<span style="color: #339933;">,</span>A
	ANL	A<span style="color: #339933;">,</span>#<span style="color: #0000ff;">0FH</span>
	MOVC	A<span style="color: #339933;">,</span>@A<span style="color: #339933;">+</span>DPTR
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R3<span style="color: #339933;">,</span>A
	<span style="color: #00007f; font-weight: bold;">MOV</span>	A<span style="color: #339933;">,</span>R2
	SWAP	A
	ANL	A<span style="color: #339933;">,</span>#<span style="color: #0000ff;">0FH</span>
	MOVC	A<span style="color: #339933;">,</span>@A<span style="color: #339933;">+</span>DPTR
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R4<span style="color: #339933;">,</span>A
	<span style="color: #00007f; font-weight: bold;">POP</span>	DPL
	<span style="color: #00007f; font-weight: bold;">POP</span>	DPH
	<span style="color: #00007f; font-weight: bold;">POP</span>	<span style="color: #0000ff;">02H</span>
	<span style="color: #00007f; font-weight: bold;">RET</span>  
<span style="color: #666666; font-style: italic;">;*******************************************************************</span>
<span style="color: #666666; font-style: italic;">;          中断服务程序 INT_7290:（INT0）</span>
<span style="color: #666666; font-style: italic;">;*******************************************************************	</span>
INT_7290<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span>	<span style="color: #0000ff;">00H</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span>	<span style="color: #0000ff;">02H</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span>	<span style="color: #0000ff;">03H</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span>	<span style="color: #0000ff;">04H</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span>	<span style="color: #0000ff;">07H</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span>	ACC
	<span style="color: #00007f; font-weight: bold;">PUSH</span>	PSW
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R0<span style="color: #339933;">,</span>#<span style="color: #0000ff;">28H</span>	<span style="color: #666666; font-style: italic;">;状态数据区首址</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R7<span style="color: #339933;">,</span>#<span style="color: #0000ff;">04H</span>	<span style="color: #666666; font-style: italic;">;取状态数据个数</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R2<span style="color: #339933;">,</span>#<span style="color: #0000ff;">00H</span> <span style="color: #666666; font-style: italic;">;内部数据首地址</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R3<span style="color: #339933;">,</span>#WSLA<span style="color: #666666; font-style: italic;">;取器件地址（写）</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R4<span style="color: #339933;">,</span>#RSLA<span style="color: #666666; font-style: italic;">;取器件地址（读）</span>
 	LCALL	RDADD	<span style="color: #666666; font-style: italic;">;读出7290的00H-03H数据存于28H-2BH </span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>			<span style="color: #666666; font-style: italic;">;设定一个断点,以观察读出的4个数据</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	A<span style="color: #339933;">,</span><span style="color: #0000ff;">29H</span>	<span style="color: #666666; font-style: italic;">;取健值</span>
	LCALL	CF		<span style="color: #666666; font-style: italic;">;拆分、查表</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	<span style="color: #0000ff;">20H</span><span style="color: #339933;">,</span>R3	<span style="color: #666666; font-style: italic;">;送显示缓冲区（最低两位数码管）</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	<span style="color: #0000ff;">21H</span><span style="color: #339933;">,</span>R4
	<span style="color: #00007f; font-weight: bold;">POP</span>	PSW
	<span style="color: #00007f; font-weight: bold;">POP</span>	ACC
	<span style="color: #00007f; font-weight: bold;">POP</span>	<span style="color: #0000ff;">07H</span>
	<span style="color: #00007f; font-weight: bold;">POP</span>	<span style="color: #0000ff;">04H</span>
	<span style="color: #00007f; font-weight: bold;">POP</span>	<span style="color: #0000ff;">03H</span>
	<span style="color: #00007f; font-weight: bold;">POP</span>	<span style="color: #0000ff;">02H</span>
	<span style="color: #00007f; font-weight: bold;">POP</span>	<span style="color: #0000ff;">00H</span>
	RETI
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
DELAY<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">PUSH</span>	<span style="color: #0000ff;">00H</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span>	<span style="color: #0000ff;">01H</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>	R0<span style="color: #339933;">,</span>#<span style="color: #0000ff;">00H</span>
DELAY1<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">MOV</span>	R1<span style="color: #339933;">,</span>#<span style="color: #0000ff;">00H</span>
	DJNZ	R1<span style="color: #339933;">,</span>$
	DJNZ	R0<span style="color: #339933;">,</span>DELAY1
	<span style="color: #00007f; font-weight: bold;">POP</span>	<span style="color: #0000ff;">01H</span>
	<span style="color: #00007f; font-weight: bold;">POP</span>	<span style="color: #0000ff;">00H</span>
	<span style="color: #00007f; font-weight: bold;">RET</span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
&nbsp;
<span style="color: #666666; font-style: italic;">;相关的I2C子程序（WRNBYT、WRBYT、STOP、CACK、STA）参见8.1.4 。这里省略</span>
<span style="color: #666666; font-style: italic;">;*******************************************************************</span>
<span style="color: #666666; font-style: italic;">;【附录一】由汇编语言编制的I2C通讯子程序</span>
<span style="color: #666666; font-style: italic;">;【提  示】下列程序是在系统时钟为12MHZ（或11.0592MHZ），即NOP指令为1微秒左右。</span>
<span style="color: #666666; font-style: italic;">;（1）带有内部单元地址的多字节写操作子程序 WRNBYT</span>
<span style="color: #666666; font-style: italic;">;*******************************************************************</span>
<span style="color: #666666; font-style: italic;">;通用的I2C通讯子程序（多字节写操作）</span>
<span style="color: #666666; font-style: italic;">;入口参数R7字节数,R0:源数据块首地址</span>
<span style="color: #666666; font-style: italic;">;R0原数据块首地址；R2从器件内部子地址;R3:外围器件地址（写）</span>
<span style="color: #666666; font-style: italic;">;相关子程序WRBYT、STOP、CACK、STA</span>
<span style="color: #666666; font-style: italic;">;*******************************************************************	</span>
WRNBYT<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">PUSH</span>	PSW		
		<span style="color: #00007f; font-weight: bold;">PUSH</span>	ACC				
WRADD<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">MOV</span>		A<span style="color: #339933;">,</span>R3		<span style="color: #666666; font-style: italic;">;取外围器件地地址（包含r/w=0）	</span>
		LCALL	STA		<span style="color: #666666; font-style: italic;">;发送起始信号S  </span>
		LCALL	WRBYT		<span style="color: #666666; font-style: italic;">;发送外围地址</span>
		LCALL	CACK		<span style="color: #666666; font-style: italic;">;检测外围器件的应答信号</span>
		<span style="color: #00007f; font-weight: bold;">JB</span>		F0<span style="color: #339933;">,</span>WRADD	<span style="color: #666666; font-style: italic;">;如果应</span>
		<span style="color: #00007f; font-weight: bold;">MOV</span>		A<span style="color: #339933;">,</span>R2
		LCALL	WRBYT		<span style="color: #666666; font-style: italic;">;发送内部寄存器首地址</span>
		LCALL	CACK		<span style="color: #666666; font-style: italic;">;检测外围器件的应答信号</span>
		<span style="color: #00007f; font-weight: bold;">JB</span>		F0<span style="color: #339933;">,</span>WRADD	<span style="color: #666666; font-style: italic;">;如果应答不正确返回重来 	</span>
WRDA<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">MOV</span>		A<span style="color: #339933;">,</span>@R0
		LCALL	WRBYT		<span style="color: #666666; font-style: italic;">;发送外围地址</span>
		LCALL	CACK		<span style="color: #666666; font-style: italic;">;检测外围器件的应答信号</span>
		<span style="color: #00007f; font-weight: bold;">JB</span>		F0<span style="color: #339933;">,</span>WRADD	<span style="color: #666666; font-style: italic;">;如果应答不正确返回重来</span>
		<span style="color: #00007f; font-weight: bold;">INC</span>		R0
		DJNZ  	R7<span style="color: #339933;">,</span>WRDA
		LCALL	STOP 	
		<span style="color: #00007f; font-weight: bold;">POP</span>		ACC
		<span style="color: #00007f; font-weight: bold;">POP</span>		PSW
		<span style="color: #00007f; font-weight: bold;">RET</span> 	       
<span style="color: #666666; font-style: italic;">;*******************************************************************</span>
&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">;（2）带有内部单元地址的多字节读操作子程序 RDADD </span>
<span style="color: #666666; font-style: italic;">;*******************************************************************</span>
<span style="color: #666666; font-style: italic;">;通用的I2C通讯子程序（多字节读操作）</span>
<span style="color: #666666; font-style: italic;">;入口参数R7字节数；</span>
<span style="color: #666666; font-style: italic;">;R0目标数据块首地址；R2从器件内部子地址；</span>
<span style="color: #666666; font-style: italic;">;R3器件地址（写）；R4器件地址（读）</span>
<span style="color: #666666; font-style: italic;">;相关子程序WRBYT、STOP、CACK、STA、MNACK </span>
<span style="color: #666666; font-style: italic;">;*******************************************************************	</span>
RDADD<span style="color: #339933;">:</span>  <span style="color: #00007f; font-weight: bold;">PUSH</span>	PSW			<span style="color: #666666; font-style: italic;">;从PCF8563的02H单元读入7个参数</span>
		<span style="color: #00007f; font-weight: bold;">PUSH</span>	ACC			<span style="color: #666666; font-style: italic;">;存放于20H-26H单元	</span>
RDADD1<span style="color: #339933;">:</span>	LCALL	STA 
		<span style="color: #00007f; font-weight: bold;">MOV</span>		A<span style="color: #339933;">,</span>R3		<span style="color: #666666; font-style: italic;">;取器件地址（写）</span>
		LCALL	WRBYT		<span style="color: #666666; font-style: italic;">;发送外围地址</span>
		LCALL	CACK		<span style="color: #666666; font-style: italic;">;检测外围器件的应答信号</span>
		<span style="color: #00007f; font-weight: bold;">JB</span>		F0<span style="color: #339933;">,</span>RDADD1	<span style="color: #666666; font-style: italic;">;如果应答不正确返回重来</span>
		<span style="color: #00007f; font-weight: bold;">MOV</span>		A<span style="color: #339933;">,</span>R2		<span style="color: #666666; font-style: italic;">;取内部地址	</span>
		LCALL	WRBYT		<span style="color: #666666; font-style: italic;">;发送外围地址</span>
		LCALL	CACK		<span style="color: #666666; font-style: italic;">;检测外围器件的应答信号</span>
		<span style="color: #00007f; font-weight: bold;">JB</span>		F0<span style="color: #339933;">,</span>RDADD1	<span style="color: #666666; font-style: italic;">;如果应答不正确返回重来	</span>
		LCALL	STA
		<span style="color: #00007f; font-weight: bold;">MOV</span>		A<span style="color: #339933;">,</span>R4		<span style="color: #666666; font-style: italic;">;取器件地址（读）</span>
		LCALL	WRBYT		<span style="color: #666666; font-style: italic;">;发送外围地址</span>
		LCALL	CACK		<span style="color: #666666; font-style: italic;">;检测外围器件的应答信号</span>
		<span style="color: #00007f; font-weight: bold;">JB</span>		F0<span style="color: #339933;">,</span>RDADD1	<span style="color: #666666; font-style: italic;">;如果应答不正确返回重来</span>
RDN<span style="color: #339933;">:</span>	LCALL	RDBYT 	
		<span style="color: #00007f; font-weight: bold;">MOV</span>		@R0<span style="color: #339933;">,</span>A
		DJNZ	R7<span style="color: #339933;">,</span>ACK
		LCALL	MNACK
		LCALL	STOP	
		<span style="color: #00007f; font-weight: bold;">POP</span>		ACC
		<span style="color: #00007f; font-weight: bold;">POP</span>		PSW
		<span style="color: #00007f; font-weight: bold;">RET</span>
ACK<span style="color: #339933;">:</span>	LCALL	MACK
		<span style="color: #00007f; font-weight: bold;">INC</span>		R0
		SJMP	RDN 
&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">;（3）I2C各个信号子程序</span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
<span style="color: #666666; font-style: italic;">;						启动信号子程序S </span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
STA<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">SETB</span>	SDA		<span style="color: #666666; font-style: italic;">;启动信号S</span>
		<span style="color: #00007f; font-weight: bold;">SETB</span>	SCL
		<span style="color: #00007f; font-weight: bold;">NOP</span>				<span style="color: #666666; font-style: italic;">;产生4.7US延时</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>	
		CLR		SDA
		<span style="color: #00007f; font-weight: bold;">NOP</span>				<span style="color: #666666; font-style: italic;">;产生4.7US延时</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span> 	
		CLR		SCL
		<span style="color: #00007f; font-weight: bold;">RET</span> 
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
<span style="color: #666666; font-style: italic;">;						停止信号子程序P </span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
STOP<span style="color: #339933;">:</span>	CLR		SDA 	<span style="color: #666666; font-style: italic;">;停止信号P</span>
		<span style="color: #00007f; font-weight: bold;">SETB</span>	SCL
		<span style="color: #00007f; font-weight: bold;">NOP</span>				<span style="color: #666666; font-style: italic;">;产生4.7US延时</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>	
		<span style="color: #00007f; font-weight: bold;">SETB</span>	SDA
		<span style="color: #00007f; font-weight: bold;">NOP</span>				<span style="color: #666666; font-style: italic;">;产生4.7US延时</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>	
		CLR		SCL
		CLR		SDA
		<span style="color: #00007f; font-weight: bold;">RET</span> 
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
<span style="color: #666666; font-style: italic;">;						应答信号子程序   MACK</span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
MACK<span style="color: #339933;">:</span>	CLR		SDA	<span style="color: #666666; font-style: italic;">;发送应答信号ACK</span>
		<span style="color: #00007f; font-weight: bold;">SETB</span>	SCL
		<span style="color: #00007f; font-weight: bold;">NOP</span>			<span style="color: #666666; font-style: italic;">;产生4.7US延时</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		CLR		SCL
		<span style="color: #00007f; font-weight: bold;">SETB</span>	SDA
		<span style="color: #00007f; font-weight: bold;">RET</span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
<span style="color: #666666; font-style: italic;">;						非应答法信号子程序MNACK</span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
MNACK<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">SETB</span>	SDA		<span style="color: #666666; font-style: italic;">;发送非应答信号NACK</span>
		<span style="color: #00007f; font-weight: bold;">SETB</span>	SCL
		<span style="color: #00007f; font-weight: bold;">NOP</span>				<span style="color: #666666; font-style: italic;">;产生4.7US延时</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		CLR		SCL
		CLR		SDA
		<span style="color: #00007f; font-weight: bold;">RET</span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
<span style="color: #666666; font-style: italic;">;						应答检测子程序CACK</span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
CACK<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">SETB</span>	SDA		<span style="color: #666666; font-style: italic;">;应答位检测子程序</span>
		<span style="color: #00007f; font-weight: bold;">SETB</span>	SCL 
		CLR		F0
		<span style="color: #00007f; font-weight: bold;">MOV</span>		<span style="color: #000000; font-weight: bold;">C</span><span style="color: #339933;">,</span>SDA	<span style="color: #666666; font-style: italic;">;采样SDA</span>
		<span style="color: #00007f; font-weight: bold;">JNC</span>		CEND	<span style="color: #666666; font-style: italic;">;应答正确时转CEND</span>
		<span style="color: #00007f; font-weight: bold;">SETB</span>	F0		<span style="color: #666666; font-style: italic;">;应答错误时F0置一</span>
CEND<span style="color: #339933;">:</span>	CLR		SCL
		<span style="color: #00007f; font-weight: bold;">RET</span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
<span style="color: #666666; font-style: italic;">;						发送一个字节子程序WRBYT</span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
WRBYT<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">PUSH</span>	<span style="color: #0000ff;">06H</span>
<span style="color: #00007f; font-weight: bold;">MOV</span>		R6<span style="color: #339933;">,</span>#<span style="color: #0000ff;">08H</span>		<span style="color: #666666; font-style: italic;">;发送一个字节子程序 </span>
WLP<span style="color: #339933;">:</span>	RLC		A 			<span style="color: #666666; font-style: italic;">;(入口参数A)</span>
		<span style="color: #00007f; font-weight: bold;">MOV</span>		SDA<span style="color: #339933;">,</span><span style="color: #000000; font-weight: bold;">C</span>
		<span style="color: #00007f; font-weight: bold;">SETB</span>	SCL
		<span style="color: #00007f; font-weight: bold;">NOP</span>					<span style="color: #666666; font-style: italic;">;产生4.7US延时</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		<span style="color: #00007f; font-weight: bold;">NOP</span>
		CLR		SCL
		DJNZ	R6<span style="color: #339933;">,</span>WLP
		<span style="color: #00007f; font-weight: bold;">POP</span>		<span style="color: #0000ff;">06H</span>
		<span style="color: #00007f; font-weight: bold;">RET</span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
<span style="color: #666666; font-style: italic;">;						接收一个字节子程序RDBYT </span>
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
RDBYT<span style="color: #339933;">:</span> 	<span style="color: #00007f; font-weight: bold;">PUSH</span>	<span style="color: #0000ff;">06H</span>
		<span style="color: #00007f; font-weight: bold;">MOV</span>		R6<span style="color: #339933;">,</span>#<span style="color: #0000ff;">08H</span>	<span style="color: #666666; font-style: italic;">;接收一个字节子程序</span>
RLP<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">SETB</span>	SDA
		<span style="color: #00007f; font-weight: bold;">SETB</span>	SCL
<span style="color: #666666; font-style: italic;">;  *******************************************</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>			<span style="color: #666666; font-style: italic;">;!!!!!产生大于15微秒的延时!!!!!!</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span> 		<span style="color: #666666; font-style: italic;">;注意这是专门为ZLG7290</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span> 		<span style="color: #666666; font-style: italic;">;添加的20微秒延时部分</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
	<span style="color: #00007f; font-weight: bold;">NOP</span>
<span style="color: #666666; font-style: italic;">;  ********************************************	</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span>		<span style="color: #000000; font-weight: bold;">C</span><span style="color: #339933;">,</span>SDA
	<span style="color: #00007f; font-weight: bold;">MOV</span>		A<span style="color: #339933;">,</span>R2
	RLC		A
	<span style="color: #00007f; font-weight: bold;">MOV</span>		R2<span style="color: #339933;">,</span>A
	CLR		SCL
	DJNZ	R6<span style="color: #339933;">,</span>RLP 		<span style="color: #666666; font-style: italic;">;(出口参数R2)</span>
	<span style="color: #00007f; font-weight: bold;">POP</span>		<span style="color: #0000ff;">06H</span>
	<span style="color: #00007f; font-weight: bold;">RET</span>  
<span style="color: #666666; font-style: italic;">;**********************************************************************</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">END</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/05/i2c-keyboard-scan-procedure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>51单片机A/D转换器</title>
		<link>http://www.dutor.net/index.php/2009/05/51-micro-controller/</link>
		<comments>http://www.dutor.net/index.php/2009/05/51-micro-controller/#comments</comments>
		<pubDate>Wed, 06 May 2009 14:18:19 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[单片机]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=375</guid>
		<description><![CDATA[
<pre lang="asm" line="1">

	dat 	bit p3.2	;定义端口号
	clk	bit p3.3	
	cs	bit p3.4

	org	8000h		;程序定位及跳转指令的设置
	ljmp	8100h
	org	8100h

start:
	mov	sp, #60h	;定义堆栈底位置
stable:
	mov	r3, #00h	;循环体执行次数:256
	mov	r6, #00h	;寄存器清零
	mov	r7, #00h	;寄存器清零
loop:
				;取平均值主要是为了减小
				;高速模数转换干扰产生的误差
	lcall	tlc549_adc	;调用模数转换子程序
	add	a, r6		;向R7-R6累加a的值256次
	mov	r6, a
	mov 	a, #00h
	addc	a, r7
	mov	r7, a	
	lcall	delay
	djnz	r3, loop
	mov	a, r7		;将R7中的平均值送到a
	cpl	a		;a取反
	mov	p1, a		;输出a的值
	sjmp	stable

tlc549_adc:			;模数转换的驱动子程序
	push	07h
	clr	a		;清零
	clr	clk		;清零
	mov	r7, #08h	;由于是串行输入，每字节需要8次读入
	clr	cs		;片选信号置低位，选中模数转换器
loop1:
	setb	clk		;开始读取数据
	mov	c, dat
	rlc	a		;诸位读取，送到a
	clr	clk
	djnz	r7, loop1
	setb	cs
	setb	clk
	pop	07h
ret

delay:				;微小的延时，用来同步和协调单片机
				;与模数转换器的工作步调
	push	00h
	mov	r0, #00h
	djnz	r0, $
	pop	00h
ret


end
</pre>
]]></description>
			<content:encoded><![CDATA[
<div class="wp_codebox"><table><tr id="p37525"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
</pre></td><td class="code" id="p375code25"><pre class="asm" style="font-family:monospace;">&nbsp;
	dat 	bit p3<span style="color: #339933;">.</span>2	<span style="color: #666666; font-style: italic;">;定义端口号</span>
	clk	bit p3<span style="color: #339933;">.</span>3	
	<span style="color: #00007f;">cs</span>	bit p3<span style="color: #339933;">.</span>4
&nbsp;
	<span style="color: #000000; font-weight: bold;">org</span>	<span style="color: #0000ff;">8000h</span>		<span style="color: #666666; font-style: italic;">;程序定位及跳转指令的设置</span>
	<span style="color: #000000; font-weight: bold;">ljmp</span>	<span style="color: #0000ff;">8100h</span>
	<span style="color: #000000; font-weight: bold;">org</span>	<span style="color: #0000ff;">8100h</span>
&nbsp;
start<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	<span style="color: #00007f;">sp</span><span style="color: #339933;">,</span> #<span style="color: #0000ff;">60h</span>	<span style="color: #666666; font-style: italic;">;定义堆栈底位置</span>
stable<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r3<span style="color: #339933;">,</span> #<span style="color: #0000ff;">00h</span>	<span style="color: #666666; font-style: italic;">;循环体执行次数:256</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">00h</span>	<span style="color: #666666; font-style: italic;">;寄存器清零</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">00h</span>	<span style="color: #666666; font-style: italic;">;寄存器清零</span>
<span style="color: #00007f; font-weight: bold;">loop</span><span style="color: #339933;">:</span>
				<span style="color: #666666; font-style: italic;">;取平均值主要是为了减小</span>
				<span style="color: #666666; font-style: italic;">;高速模数转换干扰产生的误差</span>
	lcall	tlc549_adc	<span style="color: #666666; font-style: italic;">;调用模数转换子程序</span>
	<span style="color: #00007f; font-weight: bold;">add</span>	a<span style="color: #339933;">,</span> r6		<span style="color: #666666; font-style: italic;">;向R7-R6累加a的值256次</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r6<span style="color: #339933;">,</span> a
	<span style="color: #00007f; font-weight: bold;">mov</span> 	a<span style="color: #339933;">,</span> #<span style="color: #0000ff;">00h</span>
	addc	a<span style="color: #339933;">,</span> r7
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> a	
	lcall	delay
	djnz	r3<span style="color: #339933;">,</span> <span style="color: #00007f; font-weight: bold;">loop</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	a<span style="color: #339933;">,</span> r7		<span style="color: #666666; font-style: italic;">;将R7中的平均值送到a</span>
	cpl	a		<span style="color: #666666; font-style: italic;">;a取反</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	p1<span style="color: #339933;">,</span> a		<span style="color: #666666; font-style: italic;">;输出a的值</span>
	sjmp	stable
&nbsp;
tlc549_adc<span style="color: #339933;">:</span>			<span style="color: #666666; font-style: italic;">;模数转换的驱动子程序</span>
	<span style="color: #00007f; font-weight: bold;">push</span>	<span style="color: #0000ff;">07h</span>
	clr	a		<span style="color: #666666; font-style: italic;">;清零</span>
	clr	clk		<span style="color: #666666; font-style: italic;">;清零</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">08h</span>	<span style="color: #666666; font-style: italic;">;由于是串行输入，每字节需要8次读入</span>
	clr	<span style="color: #00007f;">cs</span>		<span style="color: #666666; font-style: italic;">;片选信号置低位，选中模数转换器</span>
loop1<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">setb</span>	clk		<span style="color: #666666; font-style: italic;">;开始读取数据</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	<span style="color: #000000; font-weight: bold;">c</span><span style="color: #339933;">,</span> dat
	rlc	a		<span style="color: #666666; font-style: italic;">;诸位读取，送到a</span>
	clr	clk
	djnz	r7<span style="color: #339933;">,</span> loop1
	<span style="color: #00007f; font-weight: bold;">setb</span>	<span style="color: #00007f;">cs</span>
	<span style="color: #00007f; font-weight: bold;">setb</span>	clk
	<span style="color: #00007f; font-weight: bold;">pop</span>	<span style="color: #0000ff;">07h</span>
<span style="color: #00007f; font-weight: bold;">ret</span>
&nbsp;
delay<span style="color: #339933;">:</span>				<span style="color: #666666; font-style: italic;">;微小的延时，用来同步和协调单片机</span>
				<span style="color: #666666; font-style: italic;">;与模数转换器的工作步调</span>
	<span style="color: #00007f; font-weight: bold;">push</span>	<span style="color: #0000ff;">00h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r0<span style="color: #339933;">,</span> #<span style="color: #0000ff;">00h</span>
	djnz	r0<span style="color: #339933;">,</span> $
	<span style="color: #00007f; font-weight: bold;">pop</span>	<span style="color: #0000ff;">00h</span>
<span style="color: #00007f; font-weight: bold;">ret</span>
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">end</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/05/51-micro-controller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>单片机蜂鸣器</title>
		<link>http://www.dutor.net/index.php/2009/04/microcontroller-buzz/</link>
		<comments>http://www.dutor.net/index.php/2009/04/microcontroller-buzz/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 14:16:25 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[单片机]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=317</guid>
		<description><![CDATA[<strong>功能描述</strong>



<blockquote>功能很简单，程序更简单：</blockquote>


<blockquote>
简单的蜂鸣器实验程序：本程序通过在P1.1输出一个音频范围的方波，驱动实验板上的蜂鸣器发出蜂鸣声，其中包含有一个定时模块，作用是使输出的方波频率在人耳朵听觉能力之内的20KHZ以下，如果没有这个延时程序的话，输出的频率将大大超出人耳朵的听觉能力，我们将不能听到声音。更改定时常数，可以改变输出频率，也就可以调整蜂鸣器的音调。</blockquote>]]></description>
			<content:encoded><![CDATA[<p><strong>功能描述</strong></p>
<blockquote><p>功能很简单，程序更简单：</p></blockquote>
<blockquote><p>
简单的蜂鸣器实验程序：本程序通过在P1.1输出一个音频范围的方波，驱动实验板上的蜂鸣器发出蜂鸣声，其中包含有一个定时模块，作用是使输出的方波频率在人耳朵听觉能力之内的20KHZ以下，如果没有这个延时程序的话，输出的频率将大大超出人耳朵的听觉能力，我们将不能听到声音。更改定时常数，可以改变输出频率，也就可以调整蜂鸣器的音调。</p></blockquote>
<p><script type="text/javascript"><!--
google_ad_client = "pub-8781012522518994";
/* 468x15, chk_matlab */
google_ad_slot = "0885612183";
google_ad_width = 468;
google_ad_height = 15;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>

<div class="wp_codebox"><table><tr id="p31726"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code" id="p317code26"><pre class="asm" style="font-family:monospace;"> 	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8000h</span>		<span style="color: #666666; font-style: italic;">;定位</span>
	<span style="color: #000000; font-weight: bold;">ljmp</span> 	start
	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8100h</span>
start<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> 	<span style="color: #00007f;">sp</span><span style="color: #339933;">,</span> #<span style="color: #0000ff;">60h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	tmod<span style="color: #339933;">,</span> #<span style="color: #0000ff;">10h</span>	<span style="color: #666666; font-style: italic;">;置T1为方式1</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	tl1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">010h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	th1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">010h</span>	<span style="color: #666666; font-style: italic;">;设初值，定时为50ms</span>
	<span style="color: #00007f; font-weight: bold;">setb</span>	tr1		<span style="color: #666666; font-style: italic;">;启动定时器T1</span>
<span style="color: #00007f; font-weight: bold;">loop</span><span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">jnb</span>	tf1<span style="color: #339933;">,</span> $
&nbsp;
	clr	tf1
	<span style="color: #00007f; font-weight: bold;">mov</span>	tl1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">033h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	th1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0feh</span>
	<span style="color: #00007f; font-weight: bold;">jb</span>	p1<span style="color: #339933;">.</span>0<span style="color: #339933;">,</span> <span style="color: #00007f; font-weight: bold;">loop</span>
	cpl	p1<span style="color: #339933;">.</span>1
down<span style="color: #339933;">:</span>
	sjmp	<span style="color: #00007f; font-weight: bold;">loop</span>
	<span style="color: #000000; font-weight: bold;">END</span></pre></td></tr></table></div>

<p>[warning]This is <em>original</em> article, you could copy it freely with my site links!<br />此日志为dutor原创，您可以自由转载，添加原文链接我将万分感激！[/warning]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/04/microcontroller-buzz/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>单片机简易电子琴</title>
		<link>http://www.dutor.net/index.php/2009/04/microcontroller-simple-piano/</link>
		<comments>http://www.dutor.net/index.php/2009/04/microcontroller-simple-piano/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 14:12:53 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[单片机]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=314</guid>
		<description><![CDATA[<strong>功能描述</strong>


<blockquote>由p1口外接按键开关，p3.3接蜂鸣器组成。</blockquote>

<pre lang="asm" line="1">
 	org 	8000h		;定位
	ljmp 	start
	org 	8100h
start:
	mov 	sp, #60h
	mov	tmod, #10h	;置T1为方式1
;	mov	tl1, #010h
;	mov	th1, #010h	;设初值，定时为50ms
	setb	tr1		;启动定时器T1
</pre>]]></description>
			<content:encoded><![CDATA[<p><strong>功能描述</strong></p>
<blockquote><p>由p1口外接按键开关，p3.3接蜂鸣器组成。</p></blockquote>

<div class="wp_codebox"><table><tr id="p31427"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
</pre></td><td class="code" id="p314code27"><pre class="asm" style="font-family:monospace;"> 	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8000h</span>		<span style="color: #666666; font-style: italic;">;定位</span>
	<span style="color: #000000; font-weight: bold;">ljmp</span> 	start
	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8100h</span>
start<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> 	<span style="color: #00007f;">sp</span><span style="color: #339933;">,</span> #<span style="color: #0000ff;">60h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	tmod<span style="color: #339933;">,</span> #<span style="color: #0000ff;">10h</span>	<span style="color: #666666; font-style: italic;">;置T1为方式1</span>
<span style="color: #666666; font-style: italic;">;	mov	tl1, #010h</span>
<span style="color: #666666; font-style: italic;">;	mov	th1, #010h	;设初值，定时为50ms</span>
	<span style="color: #00007f; font-weight: bold;">setb</span>	tr1		<span style="color: #666666; font-style: italic;">;启动定时器T1</span>
&nbsp;
loop1<span style="color: #339933;">:</span>	
	<span style="color: #00007f; font-weight: bold;">mov</span>	p1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0ffh</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	a<span style="color: #339933;">,</span> p1
	<span style="color: #00007f; font-weight: bold;">mov</span>	r5<span style="color: #339933;">,</span> a
	cpl 	a
	<span style="color: #00007f; font-weight: bold;">jz</span>	loop1
	cjne	a<span style="color: #339933;">,</span> #<span style="color: #0000ff;">01h</span><span style="color: #339933;">,</span> loop2
	sjmp	do
loop2<span style="color: #339933;">:</span>
	cjne	a<span style="color: #339933;">,</span> #<span style="color: #0000ff;">02h</span><span style="color: #339933;">,</span> loop3
	sjmp	ra
loop3<span style="color: #339933;">:</span>
	cjne	a<span style="color: #339933;">,</span> #<span style="color: #0000ff;">04h</span><span style="color: #339933;">,</span> loop4
	sjmp	mi
loop4<span style="color: #339933;">:</span>
	cjne	a<span style="color: #339933;">,</span> #<span style="color: #0000ff;">08h</span><span style="color: #339933;">,</span> loop5
	sjmp	fa
loop5<span style="color: #339933;">:</span>
	cjne	a<span style="color: #339933;">,</span> #<span style="color: #0000ff;">10h</span><span style="color: #339933;">,</span> loop6
	sjmp	so
loop6<span style="color: #339933;">:</span>
	cjne	a<span style="color: #339933;">,</span> #<span style="color: #0000ff;">20h</span><span style="color: #339933;">,</span> loop7
	sjmp	la
loop7<span style="color: #339933;">:</span>
	cjne	a<span style="color: #339933;">,</span> #<span style="color: #0000ff;">40h</span><span style="color: #339933;">,</span> loop8
	sjmp	xi
loop8<span style="color: #339933;">:</span>
	cjne	a<span style="color: #339933;">,</span> #<span style="color: #0000ff;">80h</span><span style="color: #339933;">,</span> loop1
	sjmp	hdo
	sjmp	loop1
&nbsp;
do<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0f9h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">21h</span>
	sjmp	<span style="color: #00007f; font-weight: bold;">loop</span>
ra<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0f9h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0e0h</span>
	sjmp	<span style="color: #00007f; font-weight: bold;">loop</span>
mi<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0fah</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">08bh</span>
	sjmp	<span style="color: #00007f; font-weight: bold;">loop</span>
fa<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0fah</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0d7h</span>
	sjmp	<span style="color: #00007f; font-weight: bold;">loop</span>
so<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0fbh</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">67h</span>
	sjmp	<span style="color: #00007f; font-weight: bold;">loop</span>
la<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0fbh</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0e8h</span>
	sjmp	<span style="color: #00007f; font-weight: bold;">loop</span>
xi<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0fch</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">5bh</span>
	sjmp	<span style="color: #00007f; font-weight: bold;">loop</span>
hdo<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0fch</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">8eh</span>
	sjmp	<span style="color: #00007f; font-weight: bold;">loop</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">loop</span><span style="color: #339933;">:</span>
	lcall 	music
	sjmp	loop1
music<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	tl1<span style="color: #339933;">,</span> r6
	<span style="color: #00007f; font-weight: bold;">mov</span>	th1<span style="color: #339933;">,</span> r7
&nbsp;
loop9<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">jnb</span>	tf1<span style="color: #339933;">,</span> $
	clr	tf1
	<span style="color: #00007f; font-weight: bold;">mov</span>	tl1<span style="color: #339933;">,</span> r6
	<span style="color: #00007f; font-weight: bold;">mov</span>	th1<span style="color: #339933;">,</span> r7
	cpl	p3<span style="color: #339933;">.</span>3
	<span style="color: #00007f; font-weight: bold;">mov</span>	a<span style="color: #339933;">,</span> p1
	cpl	a
	<span style="color: #00007f; font-weight: bold;">jnz</span>	loop9
	<span style="color: #00007f; font-weight: bold;">setb</span>	p3<span style="color: #339933;">.</span>3
down<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">ret</span>
	<span style="color: #000000; font-weight: bold;">END</span></pre></td></tr></table></div>

<p>[warning]This is <em>original</em> article, you could copy it freely with my site links!<br />此日志为dutor原创，您可以自由转载，添加原文链接我将万分感激！[/warning]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/04/microcontroller-simple-piano/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>单片机中断实验</title>
		<link>http://www.dutor.net/index.php/2009/04/microcontroller-interrupt-experiment/</link>
		<comments>http://www.dutor.net/index.php/2009/04/microcontroller-interrupt-experiment/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 14:05:40 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[单片机]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=311</guid>
		<description><![CDATA[<strong>功能描述</strong>


<blockquote>正常情况下(p3.2为高电平), p3.3的电平以一定的频率连续翻转，当p3.2为低电平时，触发int0外部中断，进入中断服务程序，另p3.3保持低电平，并将p1端口加1。p3.2外接一个按键开关时，中断服务程序有防抖动的功能，这时通过一定的延时(通常为10ms--20ms)来实现的。</blockquote>

<strong>程序</strong>
<pre lang="asm" line="1">
 	org 	8000h		;定位
	ljmp 	start
	org 	8003h		;中断向量
	ljmp	int_0
	org 	8100h
start:
	mov 	sp, #60h
	setb	ex0		;开int0中断
	setb 	ea		;开总中断
	mov	tcon, #00h	;低电平触发
	mov	r3, #00h
	mov	a, r3
	cpl	a
loop3:				;死循环
	mov	p1, a
	cpl	p3.3		;翻转
	lcall	DELAY		;延时
	sjmp	loop3

int_0:				;中断服务子程序
	push	psw
	lcall	DELAY		;防抖动
	setb	p3.3
	inc	r3
	mov	a, r3
	cpl	a
	mov	p1, a
	jnb	p3.2, $		;查询，防止多次中断
	lcall	DELAY		;还是防抖动
	pop	psw
	reti

DELAY:  PUSH 06H
	PUSH 07H
	MOV R7, #70H
LABEL1:
	MOV R6, #70H
LABEL2:
	DJNZ R6, $
	DJNZ R7, LABEL1
	POP 07H
	POP 06H
	RET
	END
</pre>

]]></description>
			<content:encoded><![CDATA[<p><strong>功能描述</strong></p>
<blockquote><p>正常情况下(p3.2为高电平), p3.3的电平以一定的频率连续翻转，当p3.2为低电平时，触发int0外部中断，进入中断服务程序，另p3.3保持低电平，并将p1端口加1。p3.2外接一个按键开关时，中断服务程序有防抖动的功能，这时通过一定的延时(通常为10ms&#8211;20ms)来实现的。</p></blockquote>
<p><strong>程序</strong></p>

<div class="wp_codebox"><table><tr id="p31128"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
</pre></td><td class="code" id="p311code28"><pre class="asm" style="font-family:monospace;"> 	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8000h</span>		<span style="color: #666666; font-style: italic;">;定位</span>
	<span style="color: #000000; font-weight: bold;">ljmp</span> 	start
	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8003h</span>		<span style="color: #666666; font-style: italic;">;中断向量</span>
	<span style="color: #000000; font-weight: bold;">ljmp</span>	int_0
	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8100h</span>
start<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> 	<span style="color: #00007f;">sp</span><span style="color: #339933;">,</span> #<span style="color: #0000ff;">60h</span>
	<span style="color: #00007f; font-weight: bold;">setb</span>	ex0		<span style="color: #666666; font-style: italic;">;开int0中断</span>
	<span style="color: #00007f; font-weight: bold;">setb</span> 	ea		<span style="color: #666666; font-style: italic;">;开总中断</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	tcon<span style="color: #339933;">,</span> #<span style="color: #0000ff;">00h</span>	<span style="color: #666666; font-style: italic;">;低电平触发</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r3<span style="color: #339933;">,</span> #<span style="color: #0000ff;">00h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	a<span style="color: #339933;">,</span> r3
	cpl	a
loop3<span style="color: #339933;">:</span>				<span style="color: #666666; font-style: italic;">;死循环</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	p1<span style="color: #339933;">,</span> a
	cpl	p3<span style="color: #339933;">.</span>3		<span style="color: #666666; font-style: italic;">;翻转</span>
	lcall	DELAY		<span style="color: #666666; font-style: italic;">;延时</span>
	sjmp	loop3
&nbsp;
int_0<span style="color: #339933;">:</span>				<span style="color: #666666; font-style: italic;">;中断服务子程序</span>
	<span style="color: #00007f; font-weight: bold;">push</span>	psw
	lcall	DELAY		<span style="color: #666666; font-style: italic;">;防抖动</span>
	<span style="color: #00007f; font-weight: bold;">setb</span>	p3<span style="color: #339933;">.</span>3
	<span style="color: #00007f; font-weight: bold;">inc</span>	r3
	<span style="color: #00007f; font-weight: bold;">mov</span>	a<span style="color: #339933;">,</span> r3
	cpl	a
	<span style="color: #00007f; font-weight: bold;">mov</span>	p1<span style="color: #339933;">,</span> a
	<span style="color: #00007f; font-weight: bold;">jnb</span>	p3<span style="color: #339933;">.</span>2<span style="color: #339933;">,</span> $		<span style="color: #666666; font-style: italic;">;查询，防止多次中断</span>
	lcall	DELAY		<span style="color: #666666; font-style: italic;">;还是防抖动</span>
	<span style="color: #00007f; font-weight: bold;">pop</span>	psw
	reti
&nbsp;
DELAY<span style="color: #339933;">:</span>  <span style="color: #00007f; font-weight: bold;">PUSH</span> <span style="color: #0000ff;">06H</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span> <span style="color: #0000ff;">07H</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span> R7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">70H</span>
LABEL1<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span> R6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">70H</span>
LABEL2<span style="color: #339933;">:</span>
	DJNZ R6<span style="color: #339933;">,</span> $
	DJNZ R7<span style="color: #339933;">,</span> LABEL1
	<span style="color: #00007f; font-weight: bold;">POP</span> <span style="color: #0000ff;">07H</span>
	<span style="color: #00007f; font-weight: bold;">POP</span> <span style="color: #0000ff;">06H</span>
	<span style="color: #00007f; font-weight: bold;">RET</span>
	<span style="color: #000000; font-weight: bold;">END</span></pre></td></tr></table></div>

<p>[warning]This is <em>original</em> article, you could copy it freely with my site links!<br />此日志为dutor原创，您可以自由转载，添加原文链接我将万分感激！[/warning]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/04/microcontroller-interrupt-experiment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>中断方式定时器</title>
		<link>http://www.dutor.net/index.php/2009/04/interrupt-based-timer/</link>
		<comments>http://www.dutor.net/index.php/2009/04/interrupt-based-timer/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 13:54:20 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[单片机]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=307</guid>
		<description><![CDATA[89C51单片机，每计时一秒将P1端口翻转一次，晶振频率12MHz，中断方式实现。这里另外一个<a href="http://www.dutor.net/index.php/2009/04/query-based-timer-5/">查询方式</a>的实现
<pre lang="asm" line="1">
 	org 	8000h		;定位
	ljmp 	start
	org 	801bh		;中断向量
	ljmp	int_t1
	org 	8100h
start:
	mov 	sp, #60h
	mov	tmod, #10h	;置T1为方式1
	mov	tl1, 0fch
	mov	th1, #4bh	;设初值，定时为50ms
	mov	r1, #20		;中断次数，以使定时为1ms
	setb	tr1		;启动定时器T1
	clr	a		;累加器清零
	setb	et1		;T1中断允许
	setb	ea		;开总外部中断标志
	sjmp	$		;等待中断


int_t1:				;中断服务子程序
	push	psw		;保存程序状态字
	mov 	tl1, #0fch	;重装计数器
	mov	th1, #4bh
	djnz	r1, exit	;1s时间未到，返回主程序，等待下一次中断
	mov	r1, #20		;1s时间到，重装r1
	cpl	a		;a取反
	mov	p1, a		;输出a
exit:	pop	psw		;程序状态字出栈
	reti

DELAY:  PUSH 06H
	PUSH 07H
	MOV R7, #70H
LABEL1:
	MOV R6, #70H
LABEL2:
	DJNZ R6, $
	DJNZ R7, LABEL1
	POP 07H
	POP 06H
	RET
	END
</pre>]]></description>
			<content:encoded><![CDATA[<p>89C51单片机，每计时一秒将P1端口翻转一次，晶振频率12MHz，中断方式实现。这里另外一个<a href="http://www.dutor.net/index.php/2009/04/query-based-timer-5/">查询方式</a>的实现</p>

<div class="wp_codebox"><table><tr id="p30729"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="code" id="p307code29"><pre class="asm" style="font-family:monospace;"> 	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8000h</span>		<span style="color: #666666; font-style: italic;">;定位</span>
	<span style="color: #000000; font-weight: bold;">ljmp</span> 	start
	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">801bh</span>		<span style="color: #666666; font-style: italic;">;中断向量</span>
	<span style="color: #000000; font-weight: bold;">ljmp</span>	int_t1
	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8100h</span>
start<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> 	<span style="color: #00007f;">sp</span><span style="color: #339933;">,</span> #<span style="color: #0000ff;">60h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	tmod<span style="color: #339933;">,</span> #<span style="color: #0000ff;">10h</span>	<span style="color: #666666; font-style: italic;">;置T1为方式1</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	tl1<span style="color: #339933;">,</span> <span style="color: #0000ff;">0fch</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	th1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">4bh</span>	<span style="color: #666666; font-style: italic;">;设初值，定时为50ms</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">20</span>		<span style="color: #666666; font-style: italic;">;中断次数，以使定时为1ms</span>
	<span style="color: #00007f; font-weight: bold;">setb</span>	tr1		<span style="color: #666666; font-style: italic;">;启动定时器T1</span>
	clr	a		<span style="color: #666666; font-style: italic;">;累加器清零</span>
	<span style="color: #00007f; font-weight: bold;">setb</span>	et1		<span style="color: #666666; font-style: italic;">;T1中断允许</span>
	<span style="color: #00007f; font-weight: bold;">setb</span>	ea		<span style="color: #666666; font-style: italic;">;开总外部中断标志</span>
	sjmp	$		<span style="color: #666666; font-style: italic;">;等待中断</span>
&nbsp;
&nbsp;
int_t1<span style="color: #339933;">:</span>				<span style="color: #666666; font-style: italic;">;中断服务子程序</span>
	<span style="color: #00007f; font-weight: bold;">push</span>	psw		<span style="color: #666666; font-style: italic;">;保存程序状态字</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> 	tl1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0fch</span>	<span style="color: #666666; font-style: italic;">;重装计数器</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	th1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">4bh</span>
	djnz	r1<span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">exit</span>	<span style="color: #666666; font-style: italic;">;1s时间未到，返回主程序，等待下一次中断</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">20</span>		<span style="color: #666666; font-style: italic;">;1s时间到，重装r1</span>
	cpl	a		<span style="color: #666666; font-style: italic;">;a取反</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	p1<span style="color: #339933;">,</span> a		<span style="color: #666666; font-style: italic;">;输出a</span>
<span style="color: #000000; font-weight: bold;">exit</span><span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">pop</span>	psw		<span style="color: #666666; font-style: italic;">;程序状态字出栈</span>
	reti
&nbsp;
DELAY<span style="color: #339933;">:</span>  <span style="color: #00007f; font-weight: bold;">PUSH</span> <span style="color: #0000ff;">06H</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span> <span style="color: #0000ff;">07H</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span> R7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">70H</span>
LABEL1<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span> R6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">70H</span>
LABEL2<span style="color: #339933;">:</span>
	DJNZ R6<span style="color: #339933;">,</span> $
	DJNZ R7<span style="color: #339933;">,</span> LABEL1
	<span style="color: #00007f; font-weight: bold;">POP</span> <span style="color: #0000ff;">07H</span>
	<span style="color: #00007f; font-weight: bold;">POP</span> <span style="color: #0000ff;">06H</span>
	<span style="color: #00007f; font-weight: bold;">RET</span>
	<span style="color: #000000; font-weight: bold;">END</span></pre></td></tr></table></div>

<p>[warning]This is <em>original</em> article, you could copy it freely with my site links!<br />此日志为dutor原创，您可以自由转载，添加原文链接我将万分感激！[/warning]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/04/interrupt-based-timer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>查询式定时器</title>
		<link>http://www.dutor.net/index.php/2009/04/query-based-timer-5/</link>
		<comments>http://www.dutor.net/index.php/2009/04/query-based-timer-5/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 13:33:29 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[单片机]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=296</guid>
		<description><![CDATA[89C51单片机，每计时一秒将P1端口翻转一次，晶振频率12MHz，这里另外一个<a href="http://www.dutor.net/index.php/2009/04/interrupt-based-timer/">中断方式</a>的实现
<pre lang="asm" line="1">
 	org 	8000h		;定位
	ljmp 	start
	org 	8100h
start:
	mov 	sp, #60h
	mov	r1, #20	
	clr	a
	mov	tmod, #10h	;置T1为方式1
loop:	mov	tl1, 0fch
	mov	th1, #4bh	;设初值，定时为50ms
	setb	tr1		;启动定时器T1
	jnb	tf1, $		;查询TF1是否溢出

	clr	tf1		;清除溢出标志
	djnz	r1, loop	;1s时间未到，重装计数器
	mov	r1, #20		;1s时间到，重装r1
	cpl	a		;a取反
	mov	p1, a		;输出a
	ljmp	loop
	
	END
</pre>]]></description>
			<content:encoded><![CDATA[<p>89C51单片机，每计时一秒将P1端口翻转一次，晶振频率12MHz，这里另外一个<a href="http://www.dutor.net/index.php/2009/04/interrupt-based-timer/">中断方式</a>的实现</p>

<div class="wp_codebox"><table><tr id="p29630"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code" id="p296code30"><pre class="asm" style="font-family:monospace;"> 	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8000h</span>		<span style="color: #666666; font-style: italic;">;定位</span>
	<span style="color: #000000; font-weight: bold;">ljmp</span> 	start
	<span style="color: #000000; font-weight: bold;">org</span> 	<span style="color: #0000ff;">8100h</span>
start<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> 	<span style="color: #00007f;">sp</span><span style="color: #339933;">,</span> #<span style="color: #0000ff;">60h</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">20</span>	
	clr	a
	<span style="color: #00007f; font-weight: bold;">mov</span>	tmod<span style="color: #339933;">,</span> #<span style="color: #0000ff;">10h</span>	<span style="color: #666666; font-style: italic;">;置T1为方式1</span>
<span style="color: #00007f; font-weight: bold;">loop</span><span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">mov</span>	tl1<span style="color: #339933;">,</span> <span style="color: #0000ff;">0fch</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	th1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">4bh</span>	<span style="color: #666666; font-style: italic;">;设初值，定时为50ms</span>
	<span style="color: #00007f; font-weight: bold;">setb</span>	tr1		<span style="color: #666666; font-style: italic;">;启动定时器T1</span>
	<span style="color: #00007f; font-weight: bold;">jnb</span>	tf1<span style="color: #339933;">,</span> $		<span style="color: #666666; font-style: italic;">;查询TF1是否溢出</span>
&nbsp;
	clr	tf1		<span style="color: #666666; font-style: italic;">;清除溢出标志</span>
	djnz	r1<span style="color: #339933;">,</span> <span style="color: #00007f; font-weight: bold;">loop</span>	<span style="color: #666666; font-style: italic;">;1s时间未到，重装计数器</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	r1<span style="color: #339933;">,</span> #<span style="color: #0000ff;">20</span>		<span style="color: #666666; font-style: italic;">;1s时间到，重装r1</span>
	cpl	a		<span style="color: #666666; font-style: italic;">;a取反</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	p1<span style="color: #339933;">,</span> a		<span style="color: #666666; font-style: italic;">;输出a</span>
	<span style="color: #000000; font-weight: bold;">ljmp</span>	<span style="color: #00007f; font-weight: bold;">loop</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">END</span></pre></td></tr></table></div>

<p>[warning]This is <em>original</em> article, you could copy it freely with my site links!<br />此日志为dutor原创，您可以自由转载，添加原文链接我将万分感激！[/warning]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/04/query-based-timer-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Evolving Scenic Lantern C51</title>
		<link>http://www.dutor.net/index.php/2009/04/evolving-scenic-lantern-c51/</link>
		<comments>http://www.dutor.net/index.php/2009/04/evolving-scenic-lantern-c51/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 04:19:34 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[边走编程]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=142</guid>
		<description><![CDATA[<pre lang="asm" line="1">
        ORG 8000H                    ; position the localtion of the beginning of the commands
        LJMP START                  ; jump to the user's commands 
        ORG 8100H                    ; position the localtion of the program
START:	MOV R0, #08H       ; times of right or left shifts
	MOV A, #0FEH               ; set LED which is lighten
	JNB P3.2, LOOP_L           ; watch the switch which controls the shift direction
LOOP_R:	RR A                    ; branch 1: right shift
	MOV P1, A
	LCALL DELAY                 ; delay so that we can notice the flickering
	DJNZ R0, LOOP_R
	SJMP START
LOOP_L:	RL A                     ; branch 1: right shift
	MOV P1, A
	LCALL DELAY
	DJNZ R0, LOOP_L
	SJMP START	 

DELAY:  PUSH 06H                   ; subProgram impliments delaying
	PUSH 07H
	MOV R7, #0FFH
LABEL1:
	MOV R6, #0FFH
LABEL2:
	DJNZ R6, $
	DJNZ R7, LABEL1
	POP 07H
	POP 06H
	RET
	END
</pre>]]></description>
			<content:encoded><![CDATA[
<div class="wp_codebox"><table><tr id="p14231"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code" id="p142code31"><pre class="asm" style="font-family:monospace;">        <span style="color: #000000; font-weight: bold;">ORG</span> <span style="color: #0000ff;">8000H</span>                    <span style="color: #666666; font-style: italic;">; position the localtion of the beginning of the commands</span>
        <span style="color: #000000; font-weight: bold;">LJMP</span> START                  <span style="color: #666666; font-style: italic;">; jump to the user's commands </span>
        <span style="color: #000000; font-weight: bold;">ORG</span> <span style="color: #0000ff;">8100H</span>                    <span style="color: #666666; font-style: italic;">; position the localtion of the program</span>
START<span style="color: #339933;">:</span>	<span style="color: #00007f; font-weight: bold;">MOV</span> R0<span style="color: #339933;">,</span> #<span style="color: #0000ff;">08H</span>       <span style="color: #666666; font-style: italic;">; times of right or left shifts</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span> A<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0FEH</span>               <span style="color: #666666; font-style: italic;">; set LED which is lighten</span>
	<span style="color: #00007f; font-weight: bold;">JNB</span> P3<span style="color: #339933;">.</span>2<span style="color: #339933;">,</span> LOOP_L           <span style="color: #666666; font-style: italic;">; watch the switch which controls the shift direction</span>
LOOP_R<span style="color: #339933;">:</span>	RR A                    <span style="color: #666666; font-style: italic;">; branch 1: right shift</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span> P1<span style="color: #339933;">,</span> A
	LCALL DELAY                 <span style="color: #666666; font-style: italic;">; delay so that we can notice the flickering</span>
	DJNZ R0<span style="color: #339933;">,</span> LOOP_R
	SJMP START
LOOP_L<span style="color: #339933;">:</span>	RL A                     <span style="color: #666666; font-style: italic;">; branch 1: right shift</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span> P1<span style="color: #339933;">,</span> A
	LCALL DELAY
	DJNZ R0<span style="color: #339933;">,</span> LOOP_L
	SJMP START	 
&nbsp;
DELAY<span style="color: #339933;">:</span>  <span style="color: #00007f; font-weight: bold;">PUSH</span> <span style="color: #0000ff;">06H</span>                   <span style="color: #666666; font-style: italic;">; subProgram impliments delaying</span>
	<span style="color: #00007f; font-weight: bold;">PUSH</span> <span style="color: #0000ff;">07H</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span> R7<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0FFH</span>
LABEL1<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">MOV</span> R6<span style="color: #339933;">,</span> #<span style="color: #0000ff;">0FFH</span>
LABEL2<span style="color: #339933;">:</span>
	DJNZ R6<span style="color: #339933;">,</span> $
	DJNZ R7<span style="color: #339933;">,</span> LABEL1
	<span style="color: #00007f; font-weight: bold;">POP</span> <span style="color: #0000ff;">07H</span>
	<span style="color: #00007f; font-weight: bold;">POP</span> <span style="color: #0000ff;">06H</span>
	<span style="color: #00007f; font-weight: bold;">RET</span>
	<span style="color: #000000; font-weight: bold;">END</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/04/evolving-scenic-lantern-c51/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

