这个汇编程序出自《Assembly Language step by step programming with linux》第8章,用于大小写字符转换。
section .bss
Buff resb 1
section .data
section .text
global _start
_start:
nop ; This no-op keeps the debuggerhappy
Read:
mov eax,3 ; Specify sys_read call
mov ebx,0 ; Specify File Descriptor 0:Standard Input
mov ecx,Buff ; Pass offset of the buffer toread to
mov edx,1 ; Tell sys_read to read onechar from stdin
int 80h ; Call sys_read
cmp eax,0 ; Look at sys_read's returnvalue in EAX
je Exit ; Jump If Equal to 0(0 means EOF) to Exit
;or fall through to test for lowercase
cmp byte [Buff],61h ; Test input charagainst lowercase 'a'
jb Write ; If below 'a' in ASCII chart,not lowercase
cmp byte [Buff],7Ah ; Test input charagainst lowercase 'z'
ja Write ; If above 'z' in ASCII chart,not lowercase
;At this point, we have a lowercase character
sub byte [Buff],20h ; Subtract 20h fromlowercase to give uppercase...
;...and then write out the char to stdout
Write:
mov eax,4 ; Specify sys_write call
mov ebx,1 ; Specify File Descriptor 1:Standard output
mov ecx,Buff ; Pass address of thecharacter to write
mov edx,1 ; Pass number of chars towrite
int 80h ; Call sys_write...
jmp Read ; ...then go to the beginning to getanother character
Exit:
mov eax,1 ; Code for Exit Syscall
mov ebx,0 ; Return a code of zero toLinux
int 80H ; Make kernel call toexit program
Buff resb 1
表示在程序装载时为Buff分配一个字节的空间。.bss段用于存放未初始化的变量。
相对于helloworld程序,这个程序使用了3个系统调用:sys_read,sys_write和sys_exit。后面两个系统调用在helloworld程序中已经描述过,不再复述。
现在看第一个系统调用sys_read。sys_read系统调用号是3(mov eax,3)。传入参数ebx装入0,表示从标准输入读取,ecx装入Buff的地址,用于把读入的数据保存到Buff中,edx保存Buff的长度。
cmp eax,0
eax保存的是系统调用sys_read的返回值,如果返回值是0,表示读到了EOF结束符(Ctrl+D),就直接退出(jeExit)。
cmp byte [Buff],61h
比较Buff的第一个字节和’a’,注意这和AT&T的语法正好是反的。如果Buff[0]的值小于’a’,则跳转到Write标号(jb Write)。
cmp byte [Buff],7Ah
比较Buff的第一个字节和’z’,如果Buff[0]的值大于’z’,则跳转到Write标号(ja Write)。
sub byte [Buff],20h
对于’a’和’z’间的字符,都减0x20,转换成大写,再执行Write后面的语句。
jmp Read
sys_write系统调用执行完以后再跳转到Read标号。
makefile如下:
uppercaser1: uppercaser1.o
ld -m elf_i386 -o uppercaser1 uppercaser1.o
uppercaser1.o: uppercaser1.asm
nasm -f elf32 -g -F stabs uppercaser1.asm -l uppercaser1.lst
[root@bogon uppercaser1]# ./uppercaser1
a
A
z
Z
v
V
7
7
最后输入 Ctrl+D ,程序退出。