- #----------------------------------------------------------------
- # Program lab_5.s - Architektury Komputerów
- #----------------------------------------------------------------
- #
- # To compile&link: gcc -no-pie -o lab_5 lab_5.s
- # To run: ./lab_5
- #
- #----------------------------------------------------------------
- .data
- fmt_1:
- .asciz "Value = %d\n" # format string
- val_1:
- .long 6 # long number
- fmt_2:
- .string "GCD(%d, %d) = %d\n" # another format string
- var_a:
- .long 3084 # first number
- var_b:
- .long 1424 # second number
- fmt_3:
- .string "%d %d" # format string for scanf
- fmt_4:
- .string "A=%d, B=%d\n" # yet another format string
- fmt_lf:
- .string "\n" # just "\n"
- ok_num:
- .long 0 # scanf result
- argc:
- .long 0 # number of arguments
- argc_tmp:
- .long 0 # number of arguments
- argv:
- .quad 0 # address of argv[]
- env:
- .quad 0 # address of env[]
- fmt_argc:
- .string "Argc=%d\n" # format for argc
- fmt_argv:
- .string "Argv[%d]=%s\n" # format for argv
- fmt_env:
- .string "Env[%d]=%s\n" # format for env
- #----------------------------------------------------------------
- .text
- .global main
- #----------------------------------------------------------------
- main:
- push %rbp
- mov %edi, argc
- mov %edi, argc_tmp
- mov %rsi, argv
- mov %rdx, env
- mov val_1, %rsi # printf( char *fmt, long num ) - second argument to %rsi;
- mov $fmt_1, %rdi # printf( char *fmt, long num ) - first argument to %rdi;
- xor %rax, %rax # printf( char *fmt, long num ) - number of vector registers to %al
- 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 # printf( fmt ) - first argument to %rdi;
- xor %rax, %rax # printf( fmt ) - number of vector registers to %al
- call printf
- cmp $2, ok_num
- jnz no_more_numbers
- mov var_b, %rdx # printf( fmt, num1, num2 ) - third argument to %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
- #----------------------------------------------------------------
- # gcd - computes greatest common divisor
- # Arguments: %rdi - first number
- # %rsi - second number
- # Returns: %rax - gcd value
- #----------------------------------------------------------------
- .type gcd, @function
- gcd:
- cmp %rdi, %rsi # (a==b)?
- jz computed # yes
- jb b_below_a # if(b < a) goto b_below_a
- sub %rdi, %rsi # else b=b-a
- jmp gcd
- b_below_a:
- sub %rsi, %rdi # a=a-b
- jmp gcd
- computed:
- mov %rdi, %rax # result (a==b)
- ret