Chinaunix首页 | 论坛 | 博客
  • 博客访问: 90150
  • 博文数量: 34
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 275
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-13 23:05
文章分类

全部博文(34)

文章存档

2011年(1)

2010年(7)

2009年(26)

我的朋友

分类:

2009-06-29 21:45:44

A-0: Motorola-to-GNU Assembly Conversion Chart

This document contains a summary of the differences between Motorola assembly code and GNU assembly code. It's important to note that there are (were) actually several varieties of Motorola HC11 assemblers—we have done our best to handle the most common varieties in this document. However, the GNU assembler accepts a mostly different format than all of the Motorola assemblers. This is a blessing in disguise: the reward for introducing a new format is that assembly for any platform is written in very much the same format when using the GNU assembler. You can use this document to get a feel for the difference between Motorola-style and GNU-style assembly syntax.

General Differences

Description Motorola Convention GNU Convention Notes

Whitespace

Each line of code in a Motorola assembly file is divided into four tab-separated sections:

[LABEL]	OPERATION	[OPERAND [...]]	[COMMENT]

LABEL is an optional label for the line. It may optionally be followed by a colon (see "Labels and colons.")

OPERATION is either an instruction (mnemonic) or a pseudo-op (directive).

OPERAND is an operand to an instruction. There may be any number of operands depending on the line's OPERATION.

COMMENT is an optional section. By convention, comments begin with a semicolon ;, but it is ignored as part of the comment.

If a line begins with *, the entire line is ignored by the assembler (see "Comments").

In GNU assembly code, whitespace serves as a separator, but like C or Java, the type and number of whitespace characters (tab or space) is not syntactically significant; whitespace should be used to improve code readability.

(none)

Comments

* Data storage declaration
	ORG	$00
i	RMB	1	; variable i
j	RMB	1	; variable j
k	RMB	1	; variable k
/* The data storage declaration
   section */
	.sect .data
i:	.byte	# variable i
j:	.byte	# variable j
k:	.byte	# variable j

The GNU assembler recognizes two varieties of comments:

  • The C-style /* multi-line block
    comment */
  • The shell-style
    # single-line comment

Labels and colons

  • Colons after labels are optional.
  • Labels can appear on a line by themselves.
  • Colons after labels are required.
  • Labels can appear on a line by themselves.

In the Motorola assemblers, colons after labels are optional. In code written for the Motorola assembler, the colon seems to be absent more often than it appears. However, colons are required after label names in GNU assembly code.

You may find it useful to use a label on a line by itself to increase code clarity. In particular, you might want to begin a large block of code with a label on a line by itself.

An example to illustrate colon usage follows:

/* Motorola label without colon */
instr1	ldaa	#0xff

/* Gnu label with colon */
instr2:	ldaa	#0xff

Specifying numeric bases

Prefix Base
% Binary (2)
@ Octal (8)
(none) Decimal (10)
$ Hexadecimal (16)
Prefix Base
0b or 0B Binary (2)
0 Octal (8)
(none) Decimal (10)
0x or 0X Hexadecimal (16)

When specifying an immediate value in assembly, use the prefixes indicated in the tables. Remember: octal values always start with a zero, so if you mean for a decimal value to be decimal, make sure it doesn't start with a zero.

Capitalization

  • All instructions (mnemonics) and pseudo-ops (directives) are capitalized.
  • Label names are often capitalized.
  • Memory addresses and other hexadecimal values are usually capitalized.
  • All instructions (mnemonics) and pseudo-ops (directives) are in lowercase.
  • Label name case is significant (like Java or C; Globals in C are translated directly to labels!).
  • Memory addresses and other hexadecimal values are in lowercase.

The GNU assembler does not actually care what case you use for anything in your assembly programs. The capitalization discussed in the tables to the left is simply the accepted convention. You may use whatever capitalization you want to. However, there are a few caveats:

  • First, you should obviously attempt to follow the GNU convention as closely as possible. That's why it's a convention: people are expected to follow it.
  • Second, the section names (e.g., .data and .text) must be lowercase for the assembler and linker to put everything where it belongs.
  • Finally, the main symbol, if defined in an assembly routine, must be named in lowercase. The linker expects to find a routine named exactly main.

Pseudo-op Assembler Directives

Motorola Directive GNU Directive Notes
	ORG	$8000
	.sect	.data

and

	.sect	.text

Instead of using the ORG directive, divide your assembly program into data and text sections. The data section will store global variables and the text section will store your program's code. Constants can go in either the data or text section; local variables should go on the stack.

PORTD	EQU	$08
	.equ	PORTD, 0x08

Use the .equ directive instead of EQU. The argument to .equ can be a number or a label name; this is similar to a #define statement in C. Imagine that, for this example, wherever the text PORTD occurred in your code, the replacement 0x08 would be substituted instead.

	END
	.end

The GNU assembler, like all present-day assemblers, is smart enough to figure out where the end of your program is. You don't need to explicitly give an END command. However, if you insist, you can use the .end directive. All instructions after END and .end are ignored by the assembler.

BUFFER	RMB	5
	.size	BUFFER,	5

or

BUFFER:	.byte
	.byte
	.byte
	.byte
	.byte

Use the .size directive to reserve a chunk of memory for later use. The first argument to .size is the name of the label you want to associate with the beginning of the chunk of memory and the second argument is the number of bytes you want to reserve.

You can also use the .byte directive to reserve a byte of memory. The advantage to using .byte is that you can initialize the reserved bytes to some value: simply use the value as the argument to the .byte directive. For example, to initialize the first byte of BUFFER to 0: BUFFER: .byte 0x00.

BUFFER	BSZ	5
BUFFER:	.byte	0x00
	.byte	0x00
	.byte	0x00

or

BUFFER:	.byte	0x00, 0x00, 0x00

You must use the .byte directive to initialize a byte of memory to some value while reserving it.

ABC	FCB	$11, $22, $33
ABC:	.byte	0x11, 0x22, 0x33

Use the .byte directive to reserve and initialize bytes of memory.

ABC	FDB	$11,$22,$33
ABC:	.word	0x11, 0x22, 0x33

Use the .word directive to reserve and initialize words of memory. On the HC11, a word is two bytes (16 bits).

ALPHA	FCC	"DEF"
ALPHA:	.string	"DEF"

Use the .string directive to reserve memory and initialize it with a string value. This is slightly different than the Motorola assembler's FCC pseudo-op, however: the GNU assembler terminates strings with a null character (0). Therefore, ALPHA: .string "DEF" actually reserves four bytes of memory: three for the characters D, E, and F, and one for the null character.

SPACE	DCB	5,$20

or

SPACE	RMB	5
	FILL	$20,5

(depending on the assembler's syntax)

SPACE:	.byte	0x20
	.byte	0x20
	.byte	0x20
	.byte	0x20
	.byte	0x20

Instead of using the DCB or FILL directive, use the .byte directive with the GNU assembler.

HC11 Instructions Recognized by the GNU Assembler

The GNU assembler can print the full set of instructions it recognizes:

m6811-elf-as --print-opcodes | less

This list follows below:

aba   
abx   
aby   
adca    [#]  [*]  []  [,X]  [,X]
adcb    [#]  [*]  []  [,X]  [,X]
adda    [#]  [*]  []  [,X]  [,X]
addb    [#]  [*]  []  [,X]  [,X]
addd    [#]  [*]  []  [,X]  [,X]
anda    [#]  [*]  []  [,X]  [,X]
andb    [#]  [*]  []  [,X]  [,X]
asl     []  [,X]  [,X]
asla  
aslb  
asld  
asr     []  [,X]  [,X]
asra  
asrb  
bcc     [

You will notice that there are several possible operands accepted by each instruction. Of course, the possible operands accepted depend on the instruction—refer to your textbook for details. A description of each possible operand follows:

  • #: 8-bit immediate value. The value must begin with the # sign.
  • #: 16-bit immediate value. The value must begin with the # sign.
  • *: an 8-bit address or a label. This may only refer to the first 256 bytes of memory (addresses 0x00 through 0xff). The value (or label name) must begin with the * character. If you specify a label name, it must refer to a location within the first 256 bytes of memory.
  • : a 16-bit address or a label. This may refer to any address in the HC11's 64 kilobytes of memory.
  • ,X, ,Y: a signed 8-bit offset from the address contained in the X (or Y) register. The value must end with ,X (or ,Y).
  • : the name of a label.
  • ... #: a mask value to use for the instruction. This value must begin with the # sign. Refer to the "Specifying numeric bases" section for a refresher on how to specify the value's base.

To see an example of each instruction used with each possible operand type, run the command m6811-elf-as --generate-example | less. While this information is used for GNU's debugging purposes, you may still find it useful.

 

A-2: USB-to-serial Adapter HOWTO

Setting Up the Serial Port

To use the USB-to-serial adapter in Windows, a driver must first be installed. The USB-to-serial adapters use the Prolific PL-2303 chipset for high compatibility with a wide range of serial devices. The adapters have been tested and work well with Windows XP and Windows Vista. While they may work well in other versions of Windows as well, this guide is only for Windows XP users. The USB-to-serial adapters have not been tested on Windows Vista; however, a driver is available for Windows Vista and it seems to work well. Linux users will find a working Prolific USB-to-serial adapter driver in the kernel (called USB_SERIAL_PL2303). On the lab computers, this driver is provided for you—plugging the adapter in should let it "just work."

  1. Download the Prolific USB-to-serial drivers from . (You may optionally use another version if you wish.) If you are a Windows Vista user, download the Windows Vista version of the drivers from .
  2. Unzip the downloaded file and run the PL-2303 Driver Installer.exe program. If you are a Windows Vista user, you should execute the downloaded program.
  3. After driver installation is complete, plug in the USB-to-serial adapter to a USB port. Let Windows detect the device and load the correct driver.
  4. Open Device Manager by choosing "Run…" from the Start menu and entering

    mmc %systemroot%\system32\devmgmt.msc

    and clicking OK. If you are a Windows Vista user, click the Start button and open Device Manager by entering the same command in the "Start Search" box and pressing Enter. You may need to allow Windows User Account Control to permit the action.
    Device Manager

    The Device Manager window.

  5. Expand the "Ports (COM & LPT)" node by clicking the small plus sign to the left of the node's name.
  6. Notice the "Prolific USB-to-Serial Comm Port" node. This is the USB-to-serial adapter. If the COM port number is 16, then you're done. Otherwise, continue with these instructions.
  7. Locate the node called "Prolific USB-to-Serial Comm Port" and open its properties by right clicking the node and selecting "Properties…."
  8. In the resulting window, select the "Port Settings" tab if it is not already active. Make sure the selected options match those in the picture below. Click the "Advanced…" button.
    Properties

    The "Prolific USB-to-Serial Comm Port" Properties window.

  9. In the Advanced Settings window, select COM16. This will allow moka5 to access the COM port. Also make sure that the options match those in the picture below. Click OK when you are done.
    Advanced

    The Advanced Settings window.

  10. Apply settings and close any remaining windows.

Caveats Thanks to Windows

Obviously, to use the USB-to-serial device, you must first determine the device's Windows COM port number. By following this guide, you have assigned COM16 to the USB-to-serial adapter. Unfortunately, because of design decisions related to the development of Windows, the device will probably be assigned a different COM port number every time you plug it in. Additionally, this COM port number is often unreasonably high (in my case, my adapter was assigned COM44 for no apparent reason). Because of this, it is probably necessary to check the adapter's COM port number before each use.

Using the Serial Port with Linux

Serial devices in Linux are traditionally named ttyS0, ttyS1, ttyS2, and so on. These devices, like all devices on a Linux system, would traditionally be located in the /dev/ directory. However, USB-to-serial adapters are not handled by the standard serial port driver in Linux—instead, as mentioned above, the PL2303 driver handles these. Instead of showing up in /dev/ttySn, USB-to-serial devices are named /dev/ttyUSBn. Therefore, this device name should be used in Linux instead of ttySn.

So, to conclude, on the lab computers, you should use /dev/ttyUSB0 as the serial device name.

Using m6811load with a USB-to-serial Adapter

Using the --port command-line option with m6811load allows you to specify which serial port to use for communicating with the HC11. For example, if your USB-to-serial adapter is located at /dev/ttyUSB0, then you could upload simple.s19 to the HC11 by using a command similar to this one:

m6811load --port=/dev/ttyUSB0 simple.s19

You can also use -p instead of --port to specify the serial port to use:

m6811load -p /dev/ttyUSB0 simple.s19

The /dev/ portion of the serial port specification is optional. Therefore, you could accomplish the same using:

m6811load --port=ttyUSB0 simple.s19

or, the shortest form:

m6811load -p ttyUSB0 simple.s19

If you do not specify a serial port device, m6811load will use /dev/ttyS0 as the default device. In Cygwin, it is difficult to say whether or not this will end up corresponding to your USB-to-serial adapter. Therefore, you should always use the --port option to specify the correct port. However, if you are using a system with a built-in serial port (i.e., most older desktop PCs), Cygwin's ttyS0 device probably points to this port.

Run

man m6811load

for details about m6811load's command-line options. You can also execute

m6811load --help

for a more brief summary of m6811load's command-line options.

Using the Serial Port with moka5

Assuming you have followed these directions so far, the USB-to-serial adapter should be present on your Windows system at COM16. The CS3432 virtual machine is configured to automatically connect the serial port at COM16 to the virtual machine—however, there is a caveat. The virtual machine sees the serial port as a "real" serial device, not as a USB-to-serial adapter. Therefore, the virtual machine will connect any Windows serial port at COM16 to the virtual machine at /dev/ttyS0.

What does this mean for you, the student? It's simple: you don't need to use any --port option with m6811load since the default (/dev/ttyS0) is automatically mapped to the correct serial port. In theory, as long as the USB-to-serial adapter is connected before you start the virtual machine, it should "just work."

Note: You should always have the USB-to-serial adapter connected in Windows as COM16 before you start the virtual machine. If you connect the adapter while the virtual machine is running, you will receive an error message. The reason for this is that the virtual machine is trying to connect the USB-to-serial adapter as /dev/ttyUSB0. Ordinarily, this wouldn't be a problem—however, the USB implementation of VMware (which powers moka5) is such that the USB-to-serial adapter will only work while it is connected as a native Windows device (COM16).

Using the Serial Port with Cygwin

As mentioned before, under Linux, serial devices are traditionally called ttyS0, ttyS1, ttyS2, and so on. These devices, like all devices on a Linux system, would traditionally be located in the /dev/ directory. Since Windows uses COM ports instead of these device names, Cygwin uses a creative way to allow serial devices to be referenced using their COM port numbers. Cygwin does not maintain any /dev/ directory at all. Instead, it automatically monitors system calls to devices and emulates a /dev/ directory for devices that actually exist. This means that while no /dev/ttyS0 device node actually exists in Cygwin, if a serial port is found, Cygwin may allow access to it using /dev/ttyS0. However, this presents a problem: which ttySn devices in Cygwin correspond to which COM devices in Windows?

Cygwin has solved this problem cleverly by allowing users to reference devices using their Windows COM port numbers. Like its ttySn device emulation, Cygwin also recognizes devices such as /dev/com1 or /dev/com8, for example. Naturally, these correspond to COM1 and COM8 in Windows, respectively. However, Cygwin only supports up to 16 COM ports (COM1, /dev/com1 through COM16, /dev/com16). This is why it is necessary to assign the USB-to-serial adapter a new COM port number if Windows assigns it a number above 16. We have chosen COM16 as the port number we'd like you to use.

To summarize, instead of referencing a serial device using a /dev/ttySn device, use a /dev/comn device instead. For example, if your USB-to-serial adapter is assigned COM port number 16 (COM16) in Windows, you would use the /dev/com16 device to reference it in Cygwin.

阅读(767) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~