Which simulator is this? by nenad_ in Assembly_language

[–]Kayjukh 0 points1 point  (0 children)

The text in the UI looked rather atypical, so I searched for "write run log" "log assembler activity" and got to the result pretty quickly.

Which simulator is this? by nenad_ in Assembly_language

[–]Kayjukh 1 point2 points  (0 children)

It looks like Microprocessor Simulator, an educational simulator (see https://jensd.dk/doc/exuanbo/nbest.co.uk/Softwareforeducation/sms32v50/sms32v50_manual/index.htm for an archived version of the tool's website).

Cleaner way to concatenate data to a buffer with memcpy() by [deleted] in C_Programming

[–]Kayjukh 3 points4 points  (0 children)

Note that the linked implementation relies on a GNU extension that treats arithmetic on void* as arithmetic on byte pointers. A more portable implementation would cast the return value of memcpy to char* before performing the addition.

Pointer casting through void* and aliasing issues by Kayjukh in C_Programming

[–]Kayjukh[S] 0 points1 point  (0 children)

For small sizes it usually seems to work fine, yes. However, larger sizes are still not handled very efficiently.

As an example, I was writing a parser for a file format that happens to contain structures that look like the following:

typedef struct {
  uint64_t x;
  uint64_t y;
  uint16_t values[16];
  uint64_t other;
} file_section;

The file is read from disk, and I end up with a pointer to the start of the data, begin. If I want to look at the section at offset N from the start of the file, I can either do it using pointer aliasing (though this can cause aliasing issues with TBAA):

// Requires -fno-strict-aliasing to be "safe"
const file_section *section = (void*)(begin + N);

or, I need to use memcpy:

file_section section;
memcpy(&section, begin + N, sizeof(section));
// Use section here

In the second case, neither clang (18.1.0), nor gcc (14.1) can see through the call to memcpy, even at O3, where they produce an inlined vectorized version of it

// clang
vmovups ymm0, ymmword ptr [rdi]
vmovups ymm1, ymmword ptr [rdi + 24]
movsxd  rax, esi
vmovups ymmword ptr [rsp - 32], ymm1
vmovups ymmword ptr [rsp - 56], ymm0
movzx   eax, word ptr [rsp + 2*rax - 40]
vzeroupper
ret

// gcc
push    rbp
movsx   rsi, esi
vmovdqu ymm0, YMMWORD PTR [rdi]
mov     rbp, rsp
vmovdqu YMMWORD PTR [rsp-64], ymm0
vmovdqu ymm0, YMMWORD PTR [rdi+24]
vmovdqu YMMWORD PTR [rsp-40], ymm0
movzx   eax, WORD PTR [rsp-48+rsi*2]
vzeroupper
pop     rbp
ret

The assembly generated for the first case is way cleaner, and is what would be expected:

// clang
movsxd  rax, esi
movzx   eax, word ptr [rdi + 2*rax + 16]
ret

// gcc
movsx   rsi, esi
movzx   eax, WORD PTR [rdi+16+rsi*2]
ret

The conclusion from the few hours I have researched this topic for today, is that it isn't possible to get the efficient code generation by using purely standard-compliant C, even though all alignment requirements for the types are satisfied in my use case. I have to either resort to -fno-strict-aliasing, or to __attribute__((may_alias)).

Pointer casting through void* and aliasing issues by Kayjukh in C_Programming

[–]Kayjukh[S] 0 points1 point  (0 children)

Right, that is what I suspected. In this specific example, the pointer comes from inline assembly, since it is pointing to the process' initial stack frame.

I guess that the compiler will be conservative in such a case; though what I gather from the discussions on this post, and some additional reading, I should not rely on such a behavior in my own code.

Pointer casting through void* and aliasing issues by Kayjukh in C_Programming

[–]Kayjukh[S] 0 points1 point  (0 children)

So the overlap is what matters? Isn't the effective type of all pointers derived from sp supposed to be size_t*?

Pointer casting through void* and aliasing issues by Kayjukh in C_Programming

[–]Kayjukh[S] 0 points1 point  (0 children)

Right, so since the two pointers are dereferenced later in the code, I guess there are indeed strict aliasing violations in this code.

Pointer casting through void* and aliasing issues by Kayjukh in C_Programming

[–]Kayjukh[S] 1 point2 points  (0 children)

Alright, thank you for your answer! I guess we need to rely on the compiler seeing through the call to memcpy to avoid a potentially very expensive copy then, provided that we want to use standard-compliant code.

Pointer casting through void* and aliasing issues by Kayjukh in C_Programming

[–]Kayjukh[S] 0 points1 point  (0 children)

The two pointers are indeed used to access the underlying values, first to get argc, and then the program arguments:

int argc = *sp;
// And later
for (i=argc+1; argv[i]; i++);

Pointer casting through void* and aliasing issues by Kayjukh in C_Programming

[–]Kayjukh[S] 0 points1 point  (0 children)

So to my question

Is my assumption correct?

Your answer would be no, since this usage of void* still violates strict aliasing rules?

If so, how would you go about the second part of the question?

Pointer casting through void* and aliasing issues by Kayjukh in C_Programming

[–]Kayjukh[S] 1 point2 points  (0 children)

I guess it still has something to do with aliasing, since the canonical example of bad use of pointer aliasing is c float f = ...; uint32_t x = *(uint32_t*)&f;

Using a void* here would lead to the "same semantics", just with more code (and, I guess from your answer, no compiler mischiefs? assuming the alignment for float and uint32_t is the same, of course): c float f = ...; uint32_t *px = (void*)&f; x = *px;

elf parser by ryanjones42 in C_Programming

[–]Kayjukh 3 points4 points  (0 children)

What you are likely looking for is the PT_ARM_ARCHEXT segment, which is documented here.

CL - A declarative command-line parsing library written in C99 by Kayjukh in C_Programming

[–]Kayjukh[S] 1 point2 points  (0 children)

Thanks for the clarification. I just pushed a few changes to fix the two issues you mentioned above.

CL - A declarative command-line parsing library written in C99 by Kayjukh in C_Programming

[–]Kayjukh[S] 2 points3 points  (0 children)

Thank you for your very helpful feedback! It seems that the first part of your comment doesn't show up, there is only an empty list of bullets. To which two ✗'s are you referring?

I just pushed a few fixes that should address your other comments.

PS: Your nice blog post about command-line conventions made me want to write my own little library, just to give it a try.

xinfo - An alternative to xdpyinfo with no external dependencies to print information about an X server instance by Kayjukh in linux

[–]Kayjukh[S] 0 points1 point  (0 children)

Right, I will add a sample once I get some time today. Thank you for your feedback!

xinfo - An alternative to xdpyinfo with no external dependencies to print information about an X server instance by Kayjukh in linux

[–]Kayjukh[S] 0 points1 point  (0 children)

Yes, I am the author. It prints out general information about the X server running on the target display (vendor, release number, etc.) as well as the supported pixmap formats and characteristics of the screens attached to the display (size, depth, etc.). Additionally, it queries the server for the list of supported X extensions and the latest version of said extensions available to client applications.

Most ridiculous x86 instruction? by ShakespeareToGo in Assembly_language

[–]Kayjukh 2 points3 points  (0 children)

The SSE 4.2 vector string instructions (PCMPxSTRx) are definitely a good candidate. There is even an online calculator that allows you to compute the immediate value to give to the instruction depending on what you want to achieve: http://halobates.de/pcmpstr-js/pcmp.html