Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lab/interactiune-c-assembly: Add inline exercises #193

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/inline_for.asm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/inline_for.asm
/inline_for

Why .asm?

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
PROGNAME := inline_for
include ../../utils/Makefile.generic

Comment on lines +2 to +3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
include ../../utils/Makefile.generic
include ../../utils/Makefile.generic

You have 2 trailing newlines at the end of each Makefile. Remove one of them.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: BSD-3-Clause

#include <stdio.h>

#define NUM 100

int main(void)
{
size_t n = NUM;
size_t sum = 0;

__asm__ (
"xor eax, eax\n\t" /* collect the sum in eax */
/* use ecx to go through items, start from n */
"mov ecx, %1\n"
"add_to_sum:\n\t"
"add eax, ecx\n\t"
"loopnz add_to_sum\n\t"
/* place sum in output register */
"mov %0, eax\n\t"
: "=r" (sum) /* output variable */
: "r" (n) /* input variable */
: "eax", "ecx"
); /* registers used in the assembly code */

printf("sum(%u): %u\n", n, sum);

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/inline_rotate.asm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/inline_rotate.asm
/inline_rotate

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
PROGNAME := inline_rotate
include ../../utils/Makefile.generic

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: BSD-3-Clause

#include <stdio.h>

#define NUM 0x12345678

int main(void)
{
size_t n = NUM;
size_t rot_left = 0;
size_t rot_right = 0;

__asm__ (""
/* TODO: Use rol instruction to shift n by 8 bits left.
* Place result in rot_left variable.
*/

/* TODO: Use ror instruction to shift n by 8 bits right.
* Place result in rot_right variable.
*/
/* TODO: Declare output variables - preceded by ':'. */
/* TODO: Declare input variables - preceded by ':'. */
/* TODO: Declared used registers - preceded by ':'. */
);

/* NOTE: Output variables are passed by address, input variables
* are passed by value.
*/

printf("init: 0x%08x, rot_left: 0x%08x, rot_right: 0x%08x\n",
n, rot_left, rot_right);

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/inline_cpuid.asm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/inline_cpuid.asm
/inline_rdtscp

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
PROGNAME := inline_rtdscp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PROGNAME := inline_rtdscp
PROGNAME := inline_rdtscp

include ../../utils/Makefile.generic

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rdtscp places the timestamp counter in edx:eax as a 64-bit number, not a string. In addition, it places the CPU number in ecx, but since students aren't used to multicore operations yet, I think we should ignore this register and focus on edx:eax. Change this exercise so that it uses rdtscp to calculate the time spent on some operations, like a for loop doing whatever.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two variants to the operation - rdtsc and rdtscp, where rdtscp also adds the processor type, but more importantly also acts as a barrier, so measuring time should be more correct using it. However, measuring time using the TSC is non-trivial, since you also need to account for the increment frequency.

You will need to explain what the numbers actually mean, since they don't translate directly to either seconds (you need to extract the increment frequency from somewhere - e.g., the system's journal using something like journalctl -xe -n 10000 | grep clocksource), nor processor clock cycles (most modern CPUs have invariant TSC, which means that the TSC is incremented at a frequency near the CPU's maximum frequency without turbo boosts, regardless of C/P/T states, which especially on laptops will rarely be the same as the actual CPU frequency).

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: BSD-3-Clause

#include <stdio.h>

int main(void)
{
char rdtscp_str[13];

__asm__ (""
/* TODO: Make rdtscp call and copy string in rdtscp_str.
* After rdtscp call result is placed in (EDX:EAX registers).
*/
);

rdtscp_str[12] = '\0';

printf("rdtscp string: %s\n", rdtscp_str);

return 0;
}
147 changes: 106 additions & 41 deletions laborator/content/interactiune-c-assembly/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/inline_rotate.asm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/inline_rotate.asm
/inline_rotate

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
PROGNAME := inline_rotate
include ../../../utils/Makefile.generic

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: BSD-3-Clause

#include <stdio.h>

#define NUM 0x12345678

int main(void)
{
size_t n = NUM;
size_t rot_left = 0;
size_t rot_right = 0;

__asm__ (
/* Use rol instruction to shift n by 8 bits left.
* Place result in rot_left variable.
*/
"mov eax, %1\n\t"
"rol %1, 8\n\t"
"mov %0, eax\n\t"
: "=r" (rot_left)
: "r" (n)
: "eax"
);

__asm__ (
/* Use ror instruction to shift n by 8 bits right.
* Place result in rot_right variable.
*/
"mov eax, %1\n\t"
"ror eax, 8\n\t"
"mov %0, eax\n\t"
: "=r" (rot_right)
: "r" (n)
: "eax", "ecx"
);


/* NOTE: Output variables are passed by address, input variables
* are passed by value.
*/
printf("init: 0x%08x, rot_left: 0x%08x, rot_right: 0x%08x\n",
n, rot_left, rot_right);

return 0;
}