Saturday, July 7, 2007

Under the C++ covers....literally

In my continuing studies of C++ I have been studing assembly language. Not from a standpoint that I will be authoring large programs written totally in assembly, but when you are down to your last options and trying to squeeze performance from a piece of code, taking a look at the assembly generated by the HLL (high level language) you can find things otherwise unseen.

Studies on Assembly: (get the cpu vendor id info)


#cpuid - program to get the processor vendor id
.section .data
output:
.ascii "Processor Vendor ID is 'xxxxxxxxxxxx'\n"
.section .text
.globl _start
_start:
movl $0, %eax
cpuid
movl $output, %edi
movl %ebx, 28(%edi)
movl %edx, 32(%edi)
movl %ecx, 36(%edi)
movl $4, %eax
movl $1, %ebx
movl $output, %ecx
movl $42, %edx
int $0x80
movl $1, %eax
movl $0, %ebx
int $0x80

This is a pretty simple assembly program. In the .data section there is a output label (think variable) defined. The .ascii is the "type" of data. In this case it means store ASCII string. The x's are placeholders for the real value coming later. The space for this data is reserved at compile time. The next section, .text, is where the instructions are stored for the program. The first instructions are to load the register EAX with a value of zero (literal). The next instruction is cpuid, which instructs the processor to get the id we are after. The zero value in EAX defines the CPUID output option. After the CPUID instruction is run, we must collect the result which will be in 3 output registers. The first instruction here (movl $output, $edi) creates a pointer from the output label to a register (EDI). Next we create pointers from the other 3 registers to the appropriate section of the EDI register. Now that all the results have been coorelated we can output the response. This program is using a Linux system call (int $0x80) to access the console from the kernel. This is a software interrupt (with the value 0x80). The EAX register will hold the specific instruction that will be executed when we make this interrupt. The EBX will hold the exit code that is given when the program exits. The ECX will hold the actual output (movl $output, %ecx). And the EDX register will hold the length of the string. Thats pretty much it. I will be posting more as my study of C++ and assembly continues.

No comments: