I know that Julia has a #time macro that outputs the amount of memory that is allocated, but is there any way to measure the number of assignments made in a function?
The problem is counting assignments is that by the time the machine runs the code, register or memory loads and stores no longer correspond to the assignments of the original code. For instance, the code
julia> g(x) = x^3
g (generic function with 1 method)
julia> #code_llvm g(1)
define i64 #julia_g_70778(i64) #0 {
top:
%1 = mul i64 %0, %0
%2 = mul i64 %1, %0
ret i64 %2
}
julia> #code_native g(1)
.text
Filename: REPL[7]
pushq %rbp
movq %rsp, %rbp
Source line: 1
movq %rdi, %rax
imulq %rax, %rax
imulq %rdi, %rax
popq %rbp
retq
nopw %cs:(%rax,%rax)
clearly has four "assignments", two movq and two imulq. But the original code did not have a single assignment.
The closest you can get, therefore, is to use a macro to rewrite assignments so that they increment a counter (in addition to actually doing the assigning). This will of course likely slow down your code substantially, so I do not recommend it.
Related
I am trying to code a recursive Fibonacci program in x86 Assembly (Intel AT&T syntax). I get a StackOverflow error in the form of a segmentation fault. Below is my code:
# Function signature:
# int factorial(int n)
.text
.equ n, 8
.equ fibMinus1, -4
.global fibonacci
fibonacci:
# Prologue (prepare the stack frame)
push %ebp
mov %esp, %ebp
# ECX is the non-volatile register which stores n
movl n(%ebp), %ecx
# Make space on the stack frame to store fib(n - 1)
subl $4, %esp
# If n == 0:
cmpl $0, %ecx
# return 0
je retZero
# If n == 1:
cmpl $1, %ecx
# return 1
je retOne
# EDX = fibonacci(n - 1)
decl %ecx
push %ecx
call fibonacci
movl %eax, fibMinus1(%esp)
# EAX = fibonacci(n - 2)
movl n(%ebp), %ecx
subl $2, %ecx
push %ecx
call fibonacci
# fibonacci(n - 1) + fibonacci(n - 2)
addl fibMinus1(%esp), %eax
# Epilogue (cleanup the stack frame)
mov %ebp, %esp
pop %ebp
# Return fibonacci(n - 1) + fibonacci(n - 2)
ret
retZero:
movl $0, %eax
# Epilogue (cleanup the stack frame)
mov %ebp, %esp
pop %ebp
# Return the maximum possible weight of the bags :D
ret
retOne:
movl $1, %eax
# Epilogue (cleanup the stack frame)
mov %ebp, %esp
pop %ebp
# Return the maximum possible weight of the bags :D
ret
This seems strange, considering that I modify the necessary parameters when pushing them onto the stack before the function call, and after each function call, I execute the epilogue sequence to reframe the stack to its proper position such that the proper parameters are retrieved during the next call.
My code models the following Python recursive code:
Essentially, I wrote a function that finds the GCD of two numbers recursively. I am trying to store the last value of the recursion call into firstVal, so I can print it to the screen. The way I have it written prints the all values of the recursion.
GCD proc firstVal: dword, secondVal: dword
mov edx, 0 ;clear edx for div
cmp secondVal, 0 ;if b is 0 (only way to exit recursion)
jz foundGCD ;then a is the gcd
mov eax, firstVal ;to find a mod b
div secondVal ;div a by b and check ah
mov ecx, secondVal ;old b in ecx
mov firstVal, ecx ;now store ecx in a
mov secondVal, edx ;store a mod b in b
invoke GCD, firstVal, secondVal ;recursion
foundGCD:
call crlf ;newline
mov eax, firstVal ;firstVal holds the gcd
call writedec ;I think the problem sits somewhere here?
call waitmsg
ret
GCD endp
How do I save the last value of the recursive proc?
The issue is that after the return from your recursive call, execution continues at the statement that follows the invoke GCD call: the foundGCD label, which will generate output.
What you should do after the invoke is handle the result of recursion, which in this case is a simple ret.
invoke GCD, firstVal, secondVal ;recursion
ret
With that, we can see that the recursion is tail recursion, so the recursive call can be replaced with an unconditional jump (left as an exercise for the reader).
This is the format that I need:
F(3) = F(2) + F(1) =
F(2) = (F1) + F(0) =
F(1) = 1
F(0) = 1
F(2) = 1
F(1) = 1
F(3) = 2
and this is my code, how am I going to do to get the format I want?
Please give me a hint or something that may help, thank you. I just start learning assembly language.
I only know how to show the first line like f()= the answer, but don't know how to show the process.
.data
fib1 BYTE "f(",0
fib2 BYTE ") + f(",0
fib3 BYTE ") = ",0
intVal DWORD ?
main PROC
mov edx, OFFSET fib1 ;show f(intVal)=
call WriteString
mov edx, intVal
call WriteDec
mov edx, OFFSET fib3
call WriteString
mov ecx, intVal-1
push intVal
call fib
add esp, 4
call WriteDec ;show result
call crlf
mov edx, OFFSET msg5 ;show goodbye msg
call WriteString
mov edx, OFFSET username
call WriteString
exit
main ENDP
fib PROC c
add ecx, 1
push ebp
mov ebp, esp
sub esp,4
mov eax, [ebp+8] ;get value
cmp eax,2 ;if ((n=1)or(n=2))
je S4
cmp eax,1
je S4
dec eax ;do fib(n-1)+fib(n-2)
push eax ;fib(n-1)
call fib
mov [ebp-4], eax ;store first result
dec dword ptr [esp] ;(n-1) -> (n-2)
call fib
add esp,4 ;clear
add eax,[ebp-4] ;add result and stored first result
jmp Quit
S4:
mov eax,1 ;start from 1,1
Quit:
mov esp,ebp ;restore esp
pop ebp ;restore ebp
ret
fib ENDP
END main
The code needs to output a "newline" at the end of each line of output, which could be a carriage return (00dh) followed by a linefeed (00ah) or just a linefeed (00ah) depending on the system (I don't know the irvine setup).
The indented lines should be printed from within the fib function, which means you have to save (push/pop stack) any registers that the print functions use.
The fib function needs to print out a variable number of spaces depending on the level of recursion, based on the text, 2 spaces per level of recursion.
The fib function needs to handle an input of 0 and return 0.
Note that the number of recursive calls to the fib function will be 2 * fib(n) - 1, assuming fib checks for fib(0), fib(1), fib(2) (more if it doesn't check for fib(2) ), which would be 5.94 billion calls for fib(47) = 2971215073, the max value for 32 bit unsigned integers. You may want to limit inputs to something like fib(10) = 55 or fib(11) = 89 or fib(12) = 144.
I have a odd number n and want to use (n+1)/2 as an array index. What is the best way to calculate the index? I just came up with to use Int((n+1)/2), round(Int, (n+1)/2)) and Int((n+1)//2). Which is better or don't I need to too worry about them?
For better performance, you need integer division (div or ÷) for that. / gives floating point results for integer arguments. // gives a Rational not an integer. So you need to write div(n+1, 2) or (n+1) ÷ 2. To type ÷ you can write \div and then press TAB on julia REPL, Jupyter notebook, Atom, etc.
Even if the dividend (n+1) is even, you need integer division to obtain an integer result directly, otherwise you need to convert the result to integer which will in turn be costly compared to the integer division.
You may also use right bit shift operator >> or unsigned right bit shift operator >>>, as positive integer division by 2^n corresponds to shifting bits of that integer to the right n times. Although integer division by a power of 2 will be lowered to bit shift operation(s) by the compiler, the compiled code will still have an extra step if the dividend is a signed integer (i.e. Int and not UInt). Therefore, using the right bit shift operators instead may give better performance, although this is likely to be a premature optimization and affects the readability of your code.
The results of >> and >>> with negative integers will be different than that of the integer division (div).
Also note that using unsigned right bit shift operator >>> might save you from some integer overflow issues.
div(x, y)
÷(x, y)
The quotient from Euclidean division. Computes x/y, truncated to an
integer.
julia> 3/2 # returns a floating point number
1.5
julia> julia> 4/2
2.0
julia> 3//2 # returns a Rational
3//2
# now integer divison
julia> div(3, 2) # returns an integer
1
julia> 3 ÷ 2 # this is the same as div(3, 2)
1
julia> 9 >> 1 # this divides a positive integer by 2
4
julia> 9 >>> 1 # this also divides a positive integer by 2
4
# results with negative numbers
julia> -5 ÷ 2
-2
julia> -5 >> 1
-3
julia> -5 >>> 1
9223372036854775805
# results with overflowing (wrapping-around) argument
julia> (Int8(127) + Int8(3)) ÷ 2 # 127 is the largest Int8 integer
-63
julia> (Int8(127) + Int8(3)) >> 1
-63
julia> (Int8(127) + Int8(3)) >>> 1 # still gives 65 (130 ÷ 2)
65
You can use #code_native macro to see how things are compiled to native code. Please do not forget more instructions does not necessarily imply being slower, although here it is be the case.
julia> f(a) = a ÷ 2
f (generic function with 2 methods)
julia> g(a) = a >> 1
g (generic function with 2 methods)
julia> h(a) = a >>> 1
h (generic function with 1 method)
julia> #code_native f(5)
.text
; Function f {
; Location: REPL[61]:1
; Function div; {
; Location: REPL[61]:1
movq %rdi, %rax
shrq $63, %rax
leaq (%rax,%rdi), %rax
sarq %rax
;}
retq
nop
;}
julia> #code_native g(5)
.text
; Function g {
; Location: REPL[62]:1
; Function >>; {
; Location: int.jl:448
; Function >>; {
; Location: REPL[62]:1
sarq %rdi
;}}
movq %rdi, %rax
retq
nopw (%rax,%rax)
;}
julia> #code_native h(5)
.text
; Function h {
; Location: REPL[63]:1
; Function >>>; {
; Location: int.jl:452
; Function >>>; {
; Location: REPL[63]:1
shrq %rdi
;}}
movq %rdi, %rax
retq
nopw (%rax,%rax)
;}
I'm trying to let the user enter 2 digits, the first one is the base and the second one the exponent.
These two values are stored correctly. I know this by printing them (this printing code is currently commented out).
However, my loop to calculate the answer of the base^exponent is returning a wrong value.
Can anyone point me in the right direction or even solve my problem?
This is my code:
#/**
#* The pow subroutine calculates powers of natural bases
#* and exponents.
#*
#* Arguments:
#*
#* base - the exponential base
#* exp - the exponent
#*
#* Return value: 'base' raised to the power of 'exp'.
#*/
#int pow( int base, int exp )
# {
# int total = 1;
# while !(exp <= 0){
# total = total * base;
# exp = exp -1;
# }
# return total;
# }
.bss
EXP: .long
BASE: .long
TOTAL: .long
.text
FSTR: .asciz "%d"
PSTR: .asciz "%d\n"
.global main
inout:
pushl %ebp # Prolog: push the base pointer.
movl %esp, %ebp # and copy stack pointer to EBP.
subl $4, %esp # Reserve stack space for variable
leal -4(%ebp), %eax # Load address of stack var in eax
pushl %eax # Push second argument of scanf
pushl $FSTR # Push first argument of scanf
call scanf # Call scanf
movl -4(%ebp), %eax # Move result of scanf from stack to eax
movl %ebp, %esp # Clear local variables from stack.
popl %ebp # Restore caller's base pointer.
ret # return from subroutine.
main:
call inout
movl %eax, BASE
#pushl BASE
#pushl $PSTR
#call printf
call inout
movl %eax, EXP
#pushl EXP
#pushl $PSTR
#call printf
#subl $4, %esp
#leal -4(%ebp), %eax
#movl %eax, TOTAL
movl $1, TOTAL
loop:
cmpl $0, EXP
jle end
movl TOTAL, %eax
mull BASE
movl %eax, TOTAL
decl EXP
jmp loop
end:
pushl %eax
pushl $PSTR
call printf
#addl $4, %esp #\
pushl $0 #- Clean up and exit
call exit #/
Thanks in advance.
One possibility is to single step the code in a debugger and verify that the working registers contain the expected values.