2017-03-10 7 views
1

私は、stdinstdoutを使用してバイトのシーケンスを必要とする限り、部分的に読み書きできるT0アセンブリをAT &プログラムに書きます。AT&Tアセンブリでstdinとstdoutを使用して連続読み込みと書き込みを行う

大きなラテン文字(A、B、C、D、...)だけを前方に変更するシーザー暗号スクランブラでなければなりません(AからB、BからC、CからD、 A)。

プログラムがシーケンスの最初の部分を読み込むのと同じように、他の文字をそのまま残したまま文字を変更し、変更した部分をstdoutに書き込み、次の部分を読み込んで何度も繰り返します。それは標準入力に設定すると、私は今では書くことができました何

>./executable >output.txt < input.txt 

コマンドでプログラムを実行して、標準出力ファイルを操作する必要があります最終的には

は、一部の文字量を読み込むプログラムであり、操作を行います出力を印刷し、より多くを求める。しかし、bufサイズより多くの文字を入力すると、クラッシュします。

ここでは、コードは次のとおりここ

SYSCALL32 = 0x80 

EXIT = 1 
ERR_CODE = 0 

STDIN = 0 
READ = 3 

STDOUT = 1 
WRITE = 4 

BUF_SIZE = 80 

.data 
textin: .space BUF_SIZE 
textout: .space BUF_SIZE 

.global _start 
_start: 
mov $READ, %eax 
mov $STDIN, %ebx 
mov $textin, %ecx 
mov $BUF_SIZE, %edx 

int $SYSCALL32 # reading 80 characters (buf_size) of std input 

cmp $0, %eax 
je exit #if 0 characters read exit 

xorl %esi, %esi #clering iterator for loop 

loop: 
mov textin(%esi), %al #copying 1 character from textin buf to work with 

cmp $'\n', %al 
je out 
cmp $'A', %al 
jl skip 
cmp $'Z', %al 
jg skip 
je takeCareOfZ 

add $1, %al 
jmp skip 

takeCareOfZ: 
mov $'A', %al 

skip: 
movb %al, textout(%esi) 
incl %esi 
jmp petla 

out: 
mov $WRITE, %eax 
mov $STDOUT, %ebx 
mov $textout, %ecx 
mov $BUF_SIZE, %edx 

int $SYSCALL32 #writing 80 characters to std output 

jmp _start 

exit: 
mov $EXIT, %eax 
mov $ERR_CODE, %ebx 

int $SYSCALL32 

答えて

2

は、固定サイズのバッファを使用することに関連する複雑さを除去するプログラムのバージョンです。 GDBを使用して

 .text 
     .global _start 
_start: 
     # read(STDIN_FILENO, buf, 1) 
     movl $1, %edx # size_t nbyte 
     movl $buf, %ecx # void *buf 
     movl $0, %ebx # int filedes 
     movl $3, %eax # sys_read 
     int  $0x80 

     cmp  $1, %eax  
     jne  bye   # EOF or read() error 

     cmp  $'A', (%ecx) 
     jl  output  # *buf < 'A' 

     cmp  $'Z', (%ecx) 
     jg  output  # *buf > 'Z' 
     je  z   # *buf == 'Z' 

     incl (%ecx)  # *buf >= 'A' && *buf < 'Z' 
     jmp  output 

z: 
     movl $'A', (%ecx) 

output: 
     # write(STDOUT_FILENO, buf, 1) 
     movl $1, %ebx # int filedes 
     movl $4, %eax # sys_write 
     int  $0x80 
     jmp  _start 

bye: 
     # exit(0) 
     movl $0, %ebx # int status 
     movl $1, %eax # sys_exit 
     int  $0x80 

.data 
buf: 
     .byte 0 

サンプル実行

$ gcc -nostdlib -m32 caesar.S -o caesar 
$ ./caesar 
1234 
1234 
ABC1 
BCD1 
Z12BB 
A12CC 

サンプル実行、一度に一つの命令。

gdb caesar

+0

ありがとうございました:) をあなたは私のためにすべてを明らかにすることを気にしない場合、私はあなたにいくつか質問がある:0がある 1.なぜ.BYTEた後、そこには重要ですかそのユースケースの中に何かありますか? 2.なぜ%ecxに接続されているものがあるのか​​は、大括弧で囲む必要がありますか? 'cmp $ 'A'、%ecx'ではなく、なぜ' cmp $ 'A'、(%ecx) 'ですか? – bartoszka1996

+0

'buf'は1バイトのバッファです。初期値0は決して使用されず、無関係です。 '%ecx'は' buf'と等価です。 '(%ecx)'は '* buf'に相当します。 – sigjuice

+0

gdbを使ってレジスタとメモリの変更を一度に1つの命令で観察する方法のアニメーションを取り上げました。 – sigjuice

関連する問題