# Program
#----------------------------------------------------------------
#
# To
#
.
fmt_1:
.
val_1:
.
#----------------------------------------------------------------
fmt_2:
.
vector:
var_a:
.long
count:
var_b:
.
item:
fmt_3:
.
line_no:
fmt_4:
.
itemval:
fmt_lf:
.
number:
ok_num:
.
FL_text:
argc:
.
LF_text:
argc_tmp:
.
dataend:
argv:
.
env:
.
fmt_argc:
.
fmt_argv:
.string "Argv[%d]=%s\n" # format for argv
fmt_env:
.string "Env[%d]=%s\n" # format for env
#----------------------------------------------------------------
.text
.global
.macro disp_str_64 file_id, address, length
mov $write_64, %rax
mov \file_id, %rdi
mov \address, %rsi
mov \length, %rdx
syscall
.endm
.macro exit_prog_64 exit_code
mov $exit_64, %rax
mov \exit_code, %rdi
syscall
.endm
#----------------------------------------------------------------
disp_str_64 $stdout, $FL_text, $FL_len
push %rbp
mov %edi, argc
mov %edi, argc_tmp
mov %rsi, argv
mov %rdx, env
mov val_1, %rsi #
CALL disp_vector_FL
mov $fmt_1, %rdi #
xor %rax, %rax # printf( char *fmt, long num ) - number of
disp_str_64 $stdout, $LF_text, $LF_len
call printf
again:
mov $fmt_3, %rdi
mov $var_a, %rsi
mov $var_b, %rdx
mov $0, %al
call scanf
mov %eax, ok_num
mov $fmt_lf, %rdi #
CALL disp_vector_LF
xor %rax, %rax #
exit_prog_64 $0
call printf
cmp $2, ok_num
jnz no_more_numbers
mov var_b, %rdx #
mov var_a, %rsi # printf( fmt, num1, num2 ) - second argument to %rsi;
mov $fmt_4, %rdi # printf( fmt, num1, num2 ) - first argument to %rdi;
xor %rax, %rax # printf( fmt, long num ) - number of vector registers to %al
call printf
mov var_a, %edi # nwd( long num1, long num2 ) - first argument to %rdi
mov var_b, %esi # nwd( long num1, long num2 ) - second argument to %rsi
call gcd
mov %rax, %rcx # printf( fmt, num1, num2, result ) - fourth argument to %rcx
mov var_b, %rdx # printf( fmt, num1, num2, result ) - third argument to %rdx
mov var_a, %rsi # printf( fmt, num1, num2, result ) - second argument to %rsi
mov $fmt_2, %rdi # printf( fmt, num1, num2, result ) - first argument to %rdi
mov $0, %al # printf( fmt, num1, num2, result ) - number of vector registers to %al
call printf
jmp again
no_more_numbers:
mov argc, %rsi # printf( fmt, num ) - second argument to %rsi;
mov $fmt_argc, %rdi # printf( fmt, num ) - first argument to %rdi;
xor %rax, %rax # printf( fmt, num ) - number of vector registers to %al
call printf
mov argv, %rbp # %rbp = argv;
next_argv:
mov (%rbp), %rdx # printf( fmt, num, str ) - third argument to %rdx;
mov argc, %esi
sub argc_tmp, %esi # printf( fmt, num, str ) - second argument to %rsi;
mov $fmt_argv, %rdi # printf( fmt, num, str ) - first argument to %rdi;
xor %rax, %rax # printf( fmt, num ) - number of vector registers to %al
call printf
add $8, %rbp # next argv
decl argc_tmp # argc_tmp--;
jnz next_argv #
mov env, %rbp # %rbp = env;
next_env:
cmp $0,(%rbp) # while( env[i] != NULL )
jz no_more_env
mov (%rbp), %rdx # printf( fmt, num, str ) - third argument to %rdx;
mov argc_tmp, %esi # printf( fmt, num, str ) - second argument to %rsi;
mov $fmt_env, %rdi # printf( fmt, num, str ) - first argument to %rdi;
xor %rax, %rax # printf( fmt, num ) - number of vector registers to %al
call printf
add $8, %rbp # next env
incl argc_tmp # argc_tmp++;
jmp next_env
no_more_env:
# xor %rdi, %rdi # exit( code ) - first argument to %rdi
# call exit
pop %rbp
ret
#----------------------------------------------------------------
#
# %rsi - second number
#
#
#----------------------------------------------------------------
.type
disp_vector_FL:
MOV count,%rcx
gcd:
cmp %rdi, %rsi #
XOR %rsi,%rsi
jz computed #
next_item:
MOV vector(,%rsi,4),%ebx
jb b_below_a #
CALL make_string # convert to string
push %rcx
push %rsi
disp_str_64 $stdout, $item, $item_len # display prepared string
pop %rsi
pop %rcx
INC %rsi # next element
LOOP next_item # { rcx--; if( rcx )
RET
sub %rdi, %rsi #
#----------------------------------------------------------------
#
# Function: disp_vector_LF
# Parameters: none
#
.type disp_vector_LF,@function
disp_vector_LF:
MOV count,%rcx # data count
MOV %rcx,%rsi # data index
DEC %rsi # data index--
prev_item:
MOV vector(,%rsi,4),%ebx # get data
CALL make_string # convert to string
push %rcx
push %rsi
disp_str_64 $stdout, $item, $item_len # display prepared string
pop %rsi
pop %rcx
DEC %rsi # previous element
LOOP prev_item # { rcx--; if( rcx ) goto prev_item }
RET # return to main program
#----------------------------------------------------------------
#
# Function: make_string
# Parameters: %esi - index of element
# %ebx - value of element
#
.type make_string,@function
make_string:
# MOVL $0x20202020, number
MOVW $0x2020, line_no
MOV %esi,%eax # convert index of vector element t
MOV $line_no + 2,%rdi
CALL num2dec
MOV %ebx,%eax # convert value of vector element to
MOV $number + 4,%rdi
CALL num2dec
RET # return to disp_vector function
#----------------------------------------------------------------
#
# Function: num2dec
# Parameters: %eax - value
# %rdi - address of last character
#
.type num2dec,@function
num2dec:
PUSH %rbx # save register on stack
PUSH %rdx # save register on stack
MOV $10,%ebx # divisor in EBX, dividend in EAX
nextdig:
XOR %edx,%edx # EDX = 0
DIV %ebx # EDX:EAX div EBX
ADD $'0',%dl # convert remainder (in EDX) to character
MOV %dl,(%rdi) # *(RDI) = character (decimal digit)
CMP $0,%eax # quotient in EAX
JZ empty
DEC
jmp gcd
b_below_a:
sub %rsi, %rdi #
JMP nextdig
empty:
POP %rdx
jmp gcd
computed:
mov %rdi, %rax #
POP %rbx # restore register from stack
RET # return to make_string function
#----------------------------------------------------------------
ret