9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] ASCII character conversion program in assembler
@ 2013-02-07 13:12 Alexander Kapshuk
  2013-02-07 21:02 ` Anthony Martin
  0 siblings, 1 reply; 2+ messages in thread
From: Alexander Kapshuk @ 2013-02-07 13:12 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

The program below, which I'm writing for educational purposes, is
intended to read a steam of ASCII characters on STDIN, convert any
lowercase character to its uppercase equivalent, and print the
resulting character on STDOUT. Any advice would be appreciated.
-------------------------------------------
#define        OPEN    14
#define        CREATE    22
#define        PREAD    50
#define        PWRITE    51
#define        CLOSE    4
#define        EXITS    8
#define        SYSCALL    64
#define        OREAD    0
#define        OWRITE_OTRUNC    17
#define        EOF    0
#define        RWRWR    436    //0664 file permissions
#define        BUF_SIZE    500
#define UPCONV    32
#define LCA 'a'
#define LCZ 'z'
#define STDIN 0
#define STDOUT 1
GLOBL    buf+0(SB),$BUF_SIZE  // store in bss ?
TEXT        _main+0(SB),$0
  CALL main+0(SB)
TEXT        main+0(SB),$0
start_read_lp:
  MOVL    $STDIN,4(SP)
          MOVL    $buf+0(SB),8(SP)
          MOVL    $BUF_SIZE,12(SP)
          MOVL    $PREAD,AX
          INT    $SYSCALL

          CMPL    AX,$EOF
          JLE    end_lp

          MOVL    $buf+0(SB),(SP)
          MOVL    AX,4(SP)
          CALL    conv2up+0(SB)

          MOVL    $STDOUT,4(SP)
          MOVL    $buf+0(SB),8(SP)
          MOVL    AX,12(SP)
          MOVL    $-1,16(SP)
          MOVL    $-1,20(SP)
          MOVL    $PWRITE,AX
          INT    $SYSCALL

          JMP    start_read_lp
end_lp:
  MOVL    $EXITS,AX
          INT    $SYSCALL
TEXT        conv2up+0(SB),0,$0
          MOVL    buf+0(FP),AX
          MOVL    bufsiz+4(FP),DX
          XORL    $0,CX
          CMPL    DX,$0
          JEQ    end_conv_lp
conv_lp:
  MOVB    (AX)(CX*1),BL
          CMPB    BL,$LCA     // this and next instruction return true and
          JLT    next_byte        // execution goes to next_byte.
          CMPB    BL,$LCZ
          JGT    next_byte

          SUBB    $UPCONV,BL
          MOVB    BL,(AX)(CX*1)
next_byte:
  INCL    CX
          CMPL    CX,DX
          JNE    conv_lp
end_conv_lp:
  RET



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [9fans] ASCII character conversion program in assembler
  2013-02-07 13:12 [9fans] ASCII character conversion program in assembler Alexander Kapshuk
@ 2013-02-07 21:02 ` Anthony Martin
  0 siblings, 0 replies; 2+ messages in thread
From: Anthony Martin @ 2013-02-07 21:02 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 1188 bytes --]

I have a few suggestions and corrections.

1. You have to actually allocate space for your local variables.
   This means either calculating how much space you'll need and
   annotating the TEXT pseudo-instruction or decrementing the SP
   as you go.

2. Calls into the kernel must look like normal calls. When writing
   in C, libc takes care of this for you. In assembly you have to
   do it yourself. There are two ways to do this: define a procedure
   and call it or push a fake return address onto the stack. I see
   you've chosen the latter but the former would make the code read
   nicer.

3. There's no need to but the buffer in the data section. It can
   be a local variable. See point 2.

4. The pread(2) system call takes a 64-bit offset like pwrite(2).

5. There's no need to define a procedure called main. The linker
   doesn't care as long as your code starts at _main.

6. Since you're using the address of the buffer quite frequently,
   your program will read better if you store it in a register.

7. It helps to pass informative error strings to exits(2).

I've attached a program that accomplishes the same task.

Cheers,
  Anthony

[-- Attachment #2: conv.s --]
[-- Type: text/plain, Size: 1713 bytes --]

#define STDIN  0
#define STDOUT 1
#define EOF    0

#define BUFSIZE    4096
#define BUFOFFSET  20

#define SYS_EXITS  8
#define SYS_PREAD  50
#define SYS_PWRITE 51

TEXT _main(SB),$(BUFSIZE+BUFOFFSET)
	LEAL	BUFOFFSET(SP), SI

read:
	// read into the buffer from stdin.
	MOVL	$STDIN, 0(SP)
	MOVL	SI, 4(SP)
	MOVL	$BUFSIZE, 8(SP)
	MOVL	$-1, 12(SP)
	MOVL	$-1, 16(SP)
	CALL	pread(SB)
	CMPL	AX, $EOF
	JLE	exit

	// call conv to transform lowercase ASCII to uppercase.
	MOVL	SI, 0(SP)
	MOVL	AX, 4(SP)
	CALL	conv(SB)

	// write the potentially modified buffer to stdout.
	MOVL	$STDOUT, 0(SP)
	MOVL	SI, 4(SP)
	MOVL	AX, 8(SP)
	MOVL	$-1, 12(SP)
	MOVL	$-1, 16(SP)
	CALL	pwrite(SB)
	CMPL	AX, 8(SP)
	JEQ	read
	MOVL	$writefail<>(SB), 0(SP)
	CALL	exits(SB)

exit:
	JEQ	3(PC)
	MOVL	$readfail<>(SB), 0(SP)
	CALL	exits(SB)
	MOVL	$0, 0(SP)
	CALL	exits(SB)
	RET

// void conv(char *buf, int n)
TEXT conv(SB), $0
	MOVL	buf+0(FP), SI
	MOVL	n+4(FP), AX
	MOVL	$0, CX
	CMPL	CX, AX
	JGE	done
loop:
	MOVB	(SI)(CX*1), BL
	CMPB	BL, $'a'
	JLT	5(PC)
	CMPB	BL, $'z'
	JGT	3(PC)
	SUBB	$0x20, BL
	MOVB	BL, (SI)(CX*1)
	INCL	CX
	CMPL	CX, AX
	JLT	loop
done:
	RET

// void exits(char *status)
TEXT exits(SB),$0
	MOVL	$SYS_EXITS, AX
	INT	$64
	RET

// int pread(int fd, char *buf, int n, vlong off)
TEXT pread(SB),$0
	MOVL	$SYS_PREAD, AX
	INT	$64
	RET

// int pwrite(int fd, char *buf, int n, vlong off)
TEXT pwrite(SB),$0
	MOVL	$SYS_PWRITE, AX
	INT	$64
	RET

GLOBL	readfail<>(SB),$13
DATA	readfail<>+0(SB)/8, $"read fai"
DATA	readfail<>+8(SB)/5, $"lure\z"

GLOBL	writefail<>(SB),$14
DATA	writefail<>+0(SB)/8, $"write fa"
DATA	writefail<>+8(SB)/6, $"ilure\z"

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-02-07 21:02 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-07 13:12 [9fans] ASCII character conversion program in assembler Alexander Kapshuk
2013-02-07 21:02 ` Anthony Martin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).