# Program
#----------------------------------------------------------------
#
# To compile&link: gcc -no-pie -o
# To run: .
#
.data
.
val_1:
oper_or:
.
fmt_2:
oper_xor:
.
oper_add:
.string "ADD" # ADD operation
oper_sub:
.string "SUB" # SUB operation
var_a:
.long 3084 # first number
var_b:
.long 1424 # second number
.
fmt_4:
var_oper:
.
fmt_lf:
fmt_oper:
.
ok_num:
fmt_res:
.
argc:
fmt_bad:
.
.
argv:
.quad 0 # address of argv[]
env:
.quad 0 # address of env[]
fmt_argc:
.string "Argc=%d\n"
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_tmp
jnz badnum
mov %rsi,
mov
mov val_1, %rsi
call atoi
cmp $0, %rax # result of conversion
jle badnum # bad number
mov
mov 16(%rbp), %rdi # atoi( argv[2] ) - 1st argument to %rdi;
call atoi
cmp $0, %rax # result of conversion
jle badnum # bad number
mov %eax, var_b # store numer in var_b
mov 24(%rbp), %rdi # atoi( argv[3] ) - 1st argument to %rdi;
call atoi
cmp $0, %rax # result of conversion
jle badnum # bad number
mov %eax, var_oper # store numer in var_oper
mov var_a, %rdx # %rdx contains var_a
mov var_b, %rcx # %rcx contains var_b
cmp $3, %eax # check for number of first operation
jnz check_5 # != 3, so check others
and %rcx, %rdx # result in %rdx
mov $oper_and, %rcx # name in %rcx
jmp display # jump to display code
check_5:
cmp $5, %eax # check for number of second operation
jnz check_6 # != 5, so check others
or %rcx, %rdx # result in %rdx
mov $oper_or, %rcx # name in %rcx
jmp display # jump to display code
check_6:
cmp $6, %eax # check for number of third operation
jnz check_10 # != 6, so check others
xor %rcx, %rdx # result in %rdx
mov $oper_xor, %rcx # name in %rcx
jmp display # jump to display code
check_10:
cmp $10, %eax # check for number of fourth operation
jnz check_15 # != 10, so check others
add %rcx, %rdx # result in %rdx
mov $oper_add, %rcx # name in %rcx
jmp display # jump to display code
check_15:
cmp $15, %eax # check for number of fifth operation
jnz oper_err # != 15, so error
sub %rcx, %rdx # result in %rdx
mov $oper_sub, %rcx # name in %rcx
jmp display # jump to display code
oper_err:
mov $fmt_err, %rdi # printf(
xor %rax, %rax
mov $0, %al #
call printf
jmp theend
display:
mov %rdx, var_res # store result in var_res
mov var_b, %r9 # printf( fmt, n1, n1, name, n2, n2 ) - 6th argument to %r9
mov var_b, %r8 # printf( fmt, n1, n1, name, n2, n2 ) - 5th argument to %r8
mov var_a, %rdx # printf( fmt, n1, n1, name, n2, n2 ) - 3rd argument to %rdx
mov var_a, %rsi # printf( fmt, n1, n1, name, n2, n2 ) - 2nd argument to %rsi
mov $fmt_oper, %rdi # printf( fmt, n1, n1, name, n2, n2 ) - 1st argument to %rdi
mov $0, %al # printf - number of vector registers to %al
call printf
mov
mov
mov $0, %al
call scanf
mov %eax, ok_num
mov $fmt_lf,
xor %rax, %rax
mov $0, %al #
call printf
jnz no_more_numbers
badnum:
mov
mov var_a, %rsi # printf( fmt, num1, num2 ) - second argument to %rsi;
mov $fmt_4,
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
mov $0, %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
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
#----------------------------------------------------------------
# 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