Feedback on Assembly answer - unix

I have been asked to provide a solution to the following question;
1.A) In MIPS assembly, there are many ways of copying the contents of one register into another register, using only one instruction. Write five single instructions, which each copy the contents of $s0 into $s1. You cannot use MIPS pseudo-instructions.
I have worked out the following solutions, however I am unable to find a way to "mark" them so please reply if there are "easier" ways or if you think any of the following are wrong;
add $s1, $s0, $zero
addi $s1, $s0, 0
sub $s1, $s0, $zero
lw $s1, 0($s0)
and $s1, $s0, $zero
As a further point I also have the following question, which has completely thrown me, mainly due to the double ^ involved;
1.B) If we execute the following grep command:
grep -E "^[^a][bc].*"
Which of the following lines (typed on the console) will be matched?
abc
AbX
Zc
ZcHello
aBNo
bb
bDbc
bca
cba
bbbbb
Any help is of course greatly appreciated.

4 out of 5 look fine to me.
However the operation:
lw $s1, 0($s0)
does not do what you want. The X(REG) syntax does indirect addressing. Let's say that $s0 contains 1165. In this case, lw $s1, 0($s0) would put into $s1 the value stored at memory address 1165. lw $s1, 4($s0) would put the value at memory address 1169 into $s0.
Hopefully that's clear. If not, you can google indirect addressing, or ask, and I'll try to explain it better.
If you want to test out MIPS code, there's an excellent java based MIPS simulator that lets you 'inspect' the state of the cpu, step through your program, etc:
http://courses.missouristate.edu/kenvollmar/mars/
Unfortunately I'm no grep expert so I can't help you there. As with any UNIX program, take a look at the manpage and help message:
man page:
man grep
help message:
grep --help
Hope this helps!

Related

ARM: What to do with the stack pointer?

I have the following piece of ARM Assembly Code from my professor.
I do not understand why i need to move the stack pointer to r1 and what happens exactly.
I know from the lecture, that ...
The stack pointer is pointing to the last written value on the stack.
Does pointing to always mean that the address is stored?
I managed to get the code working. But i want to improve code quality and understand what's going on. Also i am not allowed to use arithmetic operations anywhere in the program.
i tried the debugger also. but i only figured out how to watch the program counter from there.
I used
info registers sp pc
and
disas
I searched through all the options of the debugger but could not find something helpful.
In the stack pointer register is stored - i guessed - some address value.
// scan for users answer 'y'
ldr r0, =charplace
mov r1, sp # ???
bl scanf # Scan user's answer
ldr r1, =yes # Put address of 'y' in r1
ldrb r1, [r1] # Load the actual character 'y' into r1
at the start of the main function i do this:
.global main
main:
push {r4 - r7, lr} # copy values of these reg on top of the stack
sub sp, sp, #4 # needs to be replaced ! TODO
and at the end this:
end: add sp, sp, #4 # needs to be replaced ! TODO
pop {r4 - r7, pc} # copy values from the top of the stack back into these registers
The sub sp, sp, #4 allocates 4 bytes of space for a buffer. With a full descending stack, sp will point to the start of that buffer, with the other 3 bytes being at sp+1, sp+2, and sp+3 of course. The reason to move sp to r1 is that scanf needs the buffer address as second argument and r1 is used to pass that.
In gdb you can examine memory using the x command, to see the stack you can do for example x/4x $sp. See help x for format specifiers.

Why use pattern matching in OCaml

Let's consider this small function
let f x =
match x with
0 -> 1 |
_ -> x ;;
This is logically equivalent to
let f x =
if x = 0 then 1 else x ;;
What's then the purpose of pattern matching if we can achieve the same using if/else?
In your precise example, a pattern matching does not bring a lot, because you have only 2 cases, and more importantly because your pattern does not have any variable. Just write this example with if/then/else, you will understand:
let rec map f = function
[] -> []
| a::l -> let r = f a in r :: map f l
Note also that pattern matching warns you if you have redundant cases or if you forgot some cases.
Usually pattern matching allows a compiler to apply more aggressive optimization techniques. In the if/then/else expression the condition is an arbitrary expression, that can contain side effects. For example, the equality operator may do anything, so the compiler cannot, in general, rely that x=0 means that x is equal to zero. In pattern matching clauses are always constants, and matching means syntactic equality, that cannot be overloaded, so it can be easily compiled directly to assembly comparison operation. In the example with if, comparison will be in general compiled to a function call (but afaik in this case the compiler is clever enough, and the generated code would be the same).
But the main difference between if/then/else and pattern matching is that the latter is run in parallel and compiles into binary search trees embedded into the assembly, when if/then/else is just a linear sequence of comparisons (see this for more information).
Update
To satisfy OP curiosity I added some assembly output. It is not required to understand x86 assembler, one can just compare a number of instructions, to get a basic idea. You will see.
As I predicted, indeed, compiler emitted nearly the same code, that has the same performance for you example:
Function with_match has compiled into efficient code (notice that 0 in OCaml parlance is 1)
with_match:
.L101:
cmpq $1, %rax
je .L100
ret
.L100:
movq $3, %rax
ret
For function with_if compiler also emitted optimal code. The only difference is that in with_if function, the condition in jump instruction is inverted.
with_if:
.L103:
cmpq $1, %rax
jne .L102
movq $3, %rax
ret
.L102:
ret
This was possible, because compiler uses a trick, that allows him to treat
= as a special function, with some theory attached to it. But in general this is not possible, as = can be arbitrary function. We can easily confuse compiler, by adding the following line to the start of the file:
let (=) x y = x = y
Now all tricks are disabled, and compiler emits this inefficient code.
with_if:
subq $8, %rsp
.L105:
movq %rax, 0(%rsp)
movq $1, %rsi
movq %rax, %rdi
movq _caml_equal, %rax
call _caml_c_call
.L106:
movq _caml_young_ptr, %r11
movq (%r11), %r15
cmpq $1, %rax
je .L104
movq $3, %rax
addq $8, %rsp
ret
.L104:
movq 0(%rsp), %rax
addq $8, %rsp
ret
With all that said, I would like to stress, that one shouldn't prefer match over if or vice verse. A construct that is more clean and results in more readable code should be chosen. And ocaml compiler is rather good, and will emit efficient code for you.
I personally lean to more to matches, because this reflects my way of thinking. It is harder for me to reason in terms of if/then/else constructs, and whenever I read them, I mentally translate them into match with clauses. But this is my personal issue. Feel free to use whatever construct, that suits you better.
A partial pattern matching is detected :
type number = Zero | One | Two;
let f= function
Zero -> 0
| One -> 1 ;;
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
Two
val f : number -> int = <fun>

strcmp and strcmp_sse functions in libc

I've seen that in libc.so the actual type of strcmp_sse to call is decided by the function strcmp itself.
Here it is the code:
strcmp:
.text:000000000007B9F0 cmp cs:__cpu_features.kind, 0
.text:000000000007B9F7 jnz short loc_7B9FE
.text:000000000007B9F9 call __init_cpu_features
.text:000000000007B9FE
.text:000000000007B9FE loc_7B9FE: ; CODE XREF: .text:000000000007B9F7j
.text:000000000007B9FE lea rax, __strcmp_sse2_unaligned
.text:000000000007BA05 test cs:__cpu_features.cpuid._eax, 10h
.text:000000000007BA0F jnz short locret_7BA2B
.text:000000000007BA11 lea rax, __strcmp_ssse3
.text:000000000007BA18 test cs:__cpu_features.cpuid._ecx, 200h
.text:000000000007BA22 jnz short locret_7BA2B
.text:000000000007BA24 lea rax, __strcmp_sse2
.text:000000000007BA2B
.text:000000000007BA2B locret_7BA2B: ; CODE XREF: .text:000000000007BA0Fj
.text:000000000007BA2B ; .text:000000000007BA22j
.text:000000000007BA2B retn
What I do not understand is that the address of the strcmp_sse function to call is placed in rax and never actually called. Therefore I am wondering: who is going do call *rax? When?
Linux dynamic linker supports a special symbol type called STT_GNU_IFUNC. Strcmp is likely implemented as an IFUNC. 'Regular' symbols in a dynamic library are nothing more but a mapping from a name to the address. IFUNCs are a bit more complex than that: the address isn't readily available, in order to obtain it the linker must execute a piece of code from the library itself. We are seeing an example of such a peice of code here. Note that in x86_64 ABI a function returns the result in RAX.
This technique is typically used to pick the optimal implementation based on the CPU features. Please note that the selection logic runs only once; all but the first call to strcmp are fast.

What's the name of the popcount function in Julia?

What's the name of the function that tells you how many bits are set in some variable? This surely already exists in Base or maybe some standard library.
To quote Keno Fischer...
Try count_ones. As you can see it uses the popcnt instruction:
julia> code_native(count_ones,(Int64,))
.section __TEXT,__text,regular,pure_instructions
Filename: int.jl
Source line: 192
push RBP
mov RBP, RSP
Source line: 192
popcnt RAX, RDI
pop RBP
ret
Is your question in any way related to the Hacker News buzz about Replacing a 32-bit loop count variable with 64-bit introduces crazy performance deviations?

MIPS Assembly Pointer-to-a Pointer?

I think I know how to handle this case, but I just want to make sure I have it right. Say you have the following C code:
int myInt = 3;
int* myPointer = &myInt;
int** mySecondPointer = &myPointer;
P contains an address that points to a place in memory which has another address. I'd like to modify the second address. So the MIPS code:
la $t0, my_new_address
lw $t1, ($a0) # address that points to the address we want to modify
sw $t0, ($t1) # load address into memory pointed to by $t1
Is that the way you would do it?
Yes, that's correct as far as I can tell. It would have been easier if you used the same variable names (e.g. symbols instead of hard register names).
Why haven't you simply compiled the c-code and took a look at the list-file or assembly-output? I always do that when in doubt.

Resources