0

There is one exercise from my textbook:

int comp(data_t a, data_t b) {
    return a COMP b;
}

shows a general comparison between arguments a and b, where we can set the data type of the arguments by declaring data_t with a typedef declaration, and we can set the comparison by defining COMP with a #define declaration. Suppose a is in %edx and b is in %eax. For each of the following instruction sequences, determine which data types data_t (There can be multiple correct answers;you should list them all.)

cmpl %eax, %edx
setl %al

And the answer from the textbook is:

The suffix ‘l’ and the register identifiers indicate 32-bit operands, while the comparison is for a two’s complement ‘<’. We can infer that data_t must be int.

so my question is :since it asks to list all possible answers, why data_t cannot also be 'long int' and pointer which are also 32 bits?

  • 1
    well on my x86 computer sizeof(unisgned long int) is 8 not 4. – old_timer Aug 22 '18 at 02:03
  • int test ( void ) { return(sizeof(unsigned long int)); } compile to object and then disassemble, what do you see on your x86 computer? now the answer does change depending on which generation of x86, this is true, and there is a long period of time when your question made sense. – old_timer Aug 22 '18 at 02:06
  • the professor/text should have been careful about using int as the answer for the same reason they should follow their own model and use int32_t – old_timer Aug 22 '18 at 02:07
  • and since this shows both C code and assembly, why didnt you just plug in int and then long int for data_t and < for COMP and see what your compiler on your computer produced? here again I see 64 bit registers being used for long int and 32 bit registers for int. What did your compiler show when you tried it? – old_timer Aug 22 '18 at 02:11
  • of course I see a complete result of the C code not the incorrect fragment shown by the assembly provided. granted it depends on the calling standard used by the compiler that generated that example, for that example to be correct/complete the definition of int would be 8 bits or one byte and then sure a long could be, hmmm 16 or 32 bits one would assume if int is defined as 8 for that compiler. – old_timer Aug 22 '18 at 02:15
  • please apply the appropriate tag x86 or x86-64 to this question, I cannot tell from what you have provided. – old_timer Aug 22 '18 at 02:17
  • `long int` is 8 bytes on Linux, but 4 on Windows. – user253751 Aug 22 '18 at 02:28
  • @immibis that is very amusing, linux vs windows has nothing to do with the C language nor the implementation defined size. I can demonstrate on both operating systems a long int as being 4 as well as both showing an 8, as well as cross compilers with long int showing other sizes on those operating systems. that is the problem with the OP's question/assumption/understanding. Plus this is a pretty bad textbook to be learning from so that doesnt help. – old_timer Aug 22 '18 at 03:39
  • 1
    the cmpl instruction and the shown registers imply a particular size, although with compiler implementations for x86, that instruction all by itself can be generated from smaller variables. so even if you assume one specific size C has a way to resolve that across implementations and targets (operating system is irrelevant). – old_timer Aug 22 '18 at 03:45
  • Those size specific of course are converted in a header file to the traditional variables types which is what the compiler itself actually supports (as it doesnt support uint32_t ,etc), leading to this confusion. Your stdint.h has to match the compiler but is often delivered with the separately developed C library, which leads to the opportunity for failure. – old_timer Aug 22 '18 at 03:46
  • I am sure you cant, but I would find a better textbook/class/university...If this is the rare case you picked up this book to learn on your own, get a better book. If this is a book being used by a class in a particular university I assume you dont have the time/resources to find something better. Dont worry the grass is often not greener at other schools/professors/textbooks. – old_timer Aug 22 '18 at 03:48

1 Answers1

1

The very specific answer to your very specific question is because long does not have a fixed size definition. When the first 32 bit x86 processors came out and the 16 bit to 32 bit transition started, for a number of compilers int changed from 16 bit to 32 bit. But long int stayed at 32 bits. And this continued until the 64 bit x86 processors came out and a/some popular compilers changed long to be 64 bits and int stayed 32 bits.

But the definition of how bit an int or long is is the choice of the compiler author, the term "implementation defined" is used in the language specification to cover this. So it is very possible that one compiler or compiler version of the same compiler interprets long as 32 bit, and another compiler or version of the same interprets long as 64 bits for the same target. This is where stdint.h came from it is a bit of a hack but based on the age and history of the C language and the many many compilers, they didnt have much of a choice.

Now if you example compiler output further you may/will find that some compilers use the larger registers eax/rax and avoid al/bl ah/bl operations, has to do with microcoding and performance in part. So cmpl and eax/edx tell you the beginning of the story, read this straight of your assemblers documentation for its assembly language (assembly languages are defined by the assembler, the tool, not the chip/logic designer, although they will often mostly resemble the chip/ip vendors documentation). And then allow for the possibility that some copmilers can use that same specific instruction for smaller variables (but not larger of course).

But this assembly doesnt match the C code provided unless the definition of an int is 8 bits. The textbook implies the definition of an int is 32 bits. So this is a horrible and very broken example. If the rest of the textbook is like this I wish you luck. x86 is the wrong first instruction set to learn anyway, should never be used for teaching this kind of a topic. many/most others would serve you better. I am sure you probably dont have a choice though so your task is much harder.

What you can/should do is take that code, take the compiler or compilers you have and provided defines for data_t and COMP and see what you get. The _t in the C code implies the knowledge of stdint.h so use those definitions for your test code and your answer to this homework assignment.

old_timer
  • 69,149
  • 8
  • 89
  • 168