Archive for the ‘Computer’ Category

从五笔转向拼音
Thursday, June 14th, 2007

五笔还是我在高考完的时候学的,当时我们那个小地方学电脑的主要课程都是学打字,大部分出路都是打字员。学会了,过了几个月,到了学校,又忘了。当时比较有决心,坚持用五笔,没过多久就记起来了。

记得那时候还有人问我借五笔打字的书来着,不过已经有同宿舍的同学开始讲拼音输入法的好处。那时用的是智能陈桥,在机房的破机器上,切换出来要几秒钟。

用五笔也有不知道编码的时候,就用拼音打,我最开始习惯用智能ABC,微软拼音是从来不想用。到现在搜狗拼音、Google拼音盛行并传出绯闻,五笔的确是要退出普通人的生活了。

如果有一个五笔输入法可以像Google拼音一样自动网络同步,该多好。如果可以方便地修改默认的中文输入法该多好,改注册表真麻烦。如果我不添加拼音输入法,别人过来用机器又很不方便。主要就是这两点促使了我转向拼音输入法,Google拼音刚推出时用了一下,太舒服了。

当然五笔也有好处,上大一的时候同班一个MM用“恩”作QQ昵称,我问为什么,她说打不出口字旁的。。。(可能应该打ng而不是en)于是我用五笔打了个“嗯”(KLDN),看着别人的QQ昵称是自己创作的,别提多有成就感了。有时候在BBS上看到有人问,那个“有”字缺两横怎么打啊?五笔很简单,DMB,冇。又有人问,Orz那个O换成汉字是什么啊?是冏(MWKD)。尤其对着手写的花名册输入一些生僻的人名时,五笔真的有拼音起不到的实际作用。当然,可以用手写板解决。

去年到Meimei家的时候,她二哥拿着对讲机跟同楼的哥们一起打传奇。我发现他竟然用的是五笔输入——原来他不会拼音,呵呵。跟用五笔的人聊天,一出错就能辨别出来是五笔用户,比如用五笔的人打“程度”可能打出“程序”,而拼音不会,最多是“成都” :)

一个是音,一个是形。还真希望Google弄个五笔输入法出来,虽然可能性不大。

GAS编译的第一个汇编小程序
Thursday, March 16th, 2006

在Linux里写了第一个汇编小程序,呵呵,输入两个数字,计算出结果并显示。
保存为example.s,
# gcc -o example example.s

.section	.rodata
prompt:
.string	"Please input an integer:"
format:
.string	"%d"
oform:
.string "%d + %d = %dn"
.text
.globl main
.type	main, @function
main:
pushl	%ebp
movl	%esp, %ebp
subl	$32, %esp
andl	$-16, %esp
movl	$0, %eax
subl	%eax, %esp	;Instructions above have nothing meaningful.

movl	$prompt, (%esp)
call	printf		;Prompt for the first integer.
movl	%esp, %eax
addl	$20, %eax
movl	%eax, 4(%esp)
movl	$format, (%esp)
call	scanf		;Accept the first input.
movl	$prompt, (%esp)
call	printf		;Prompt for the second.
movl	%esp, %eax
addl	$16, %eax
movl	%eax, 4(%esp)
movl	$format, (%esp)
call	scanf		;Accept the second.
movl	16(%esp), %eax
addl	20(%esp), %eax	;Compute the sum of two integers
movl	%eax, 12(%esp)	;sum
movl	16(%esp), %eax
movl	%eax, 8(%esp)	;num2
movl	20(%esp), %eax
movl	%eax, 4(%esp)	;num1
movl	$oform, (%esp)
call	printf		;printf("%d + %d = %dn", num1, num2, sum);
leave
ret
AT&T assembly syntax
Sunday, March 12th, 2006

记得以前是弄过Windows里的汇编的,还调用了printf。现在不知道为什么不会弄了,只好转入Linux。现转载一篇AT&T语法格式的介绍(原文http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html):
# Register naming:
Register names are prefixed with “%”. To reference eax:

AT&T: %eax
Intel: eax

# Source/Destination Ordering:
In AT&T syntax (which is the UNIX standard, BTW) the source is always on the left, and the destination is always on the right.
So let’s load ebx with the value in eax:

AT&T: movl %eax, %ebx
Intel: mov ebx, eax

# Constant value/immediate value format:
You must prefix all constant/immediate values with “$”.
Let’s load eax with the address of the “C” variable booga, which is static.

AT&T: movl $_booga, %eax
Intel: mov eax, _booga

Now let’s load ebx with 0xd00d:

AT&T: movl $0xd00d, %ebx
Intel: mov ebx, d00dh

# Operator size specification:
You must suffix the instruction with one of b, w, or l to specify the width of the destination register as a byte, word or longword. If you omit this, GAS (GNU assembler) will attempt to guess. You don’t want GAS to guess, and guess wrong! Don’t forget it.

AT&T: movw %ax, %bx
Intel: mov bx, ax

The equivalent forms for Intel is byte ptr, word ptr, and dword ptr, but that is for when you are…
# Referencing memory:
DJGPP uses 386-protected mode, so you can forget all that real-mode addressing junk, including the restrictions on which register has what default segment, which registers can be base or index pointers. Now, we just get 6 general purpose registers. (7 if you use ebp, but be sure to restore it yourself or compile with -fomit-frame-pointer.)
Here is the canonical format for 32-bit addressing:

AT&T: immed32(basepointer,indexpointer,indexscale)
Intel: [basepointer + indexpointer*indexscale + immed32]

You could think of the formula to calculate the address as:

immed32 + basepointer + indexpointer * indexscale

You don’t have to use all those fields, but you do have to have at least 1 of immed32, basepointer and you MUST add the size suffix to the operator!
Let’s see some simple forms of memory addressing:

* Addressing a particular C variable:

AT&T: _booga
Intel: [_booga]

Note: the underscore (”_”) is how you get at static (global) C variables from assembler. This only works with global variables. Otherwise, you can use extended asm to have variables preloaded into registers for you. I address that farther down.

* Addressing what a register points to:

AT&T: (%eax)
Intel: [eax]

* Addressing a variable offset by a value in a register:

AT&T: _variable(%eax)
Intel: [eax + _variable]

* Addressing a value in an array of integers (scaling up by 4):

AT&T: _array(,%eax,4)
Intel: [eax*4 + array]

* You can also do offsets with the immediate value:

C code: *(p+1) where p is a char *
AT&T: 1(%eax) where eax has the value of p
Intel: [eax + 1]

* You can do some simple math on the immediate value:

AT&T: _struct_pointer+8

I assume you can do that with Intel format as well.

* Addressing a particular char in an array of 8-character records:
eax holds the number of the record desired. ebx has the wanted char’s offset within the record.

AT&T: _array(%ebx,%eax,8)
Intel: [ebx + eax*8 + _array]

Whew. Hopefully that covers all the addressing you’ll need to do. As a note, you can put esp into the address, but only as the base register.