i need a programming correction: what is machinelanguage?

Pages: 12
@jonnin, that last one, crc32, is a classic. About 10 years ago or so there was a contest to generate the fastest, where a 64 bit assembler version proved to be about 3 times faster than a classic C solution. It does provide a singular situation where compiler optimization may be beaten, but then that was a decade or more ago, and the optimizers have made significant leaps since then. It is also key to have a working C example upon which to compare the result, to make sure it is identical.
Niccolo how can i test 1 code that i get errors? :(
how can i learn something if i have several problems to start? :(
i know that i can print a number or even a letter with Assembler basic code. but i don't get a working code :(
yes i use a GCC compiler, so i must learn Inline Assembler code using what you shared:
1
2
3
4
 __asm__ ("movl %eax, %ebx\n\t"
          "movl $56, %esi\n\t"
          "movl %ecx, $label(%edx,%ebx,$4)\n\t"
          "movb %ah, (%ebx)");

the problem is that the compiler give me several errors... so what i can tell you?
heres the entire code:
1
2
3
4
5
6
7
8
9
//yes no includes
int main()
{
     __asm__ ("movl %eax, %ebx\n\t"
          "movl $56, %esi\n\t"
          "movl %ecx, $label(%edx,%ebx,$4)\n\t"
          "movb %ah, (%ebx)");
    return 0;
}

error messages:
1 - "junk `(%edx,%ebx,$4)' after expression"
2 - "operand type mismatch for `mov'"
i need something working and to start.. please advice me more
What operating system are you using?
windows 10
I get the same complaints from that sample code that you do, and Im not sure what its supposed to do nor what is wrong with it. This one does work for me:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
	
  uint32_t x = 0x01234567; //we want to endian flip this, expect 67 45 23 01 
  uint32_t y = 0x11111111; //y is something I can recognize but don't want to see!

asm ("movl %0, %%eax;\n\t" //move x to register
     "bswap %%eax\n\t"          //endian reverse eax 
	 "movl %%eax,%1;\n\t" //move eax back to variable (y)
    : "=r" (y)                            //define variables
	: "r" (x));

printf("%X\n", x);  //x is undamaged. 
printf("%X", y);     //y has expected value. 


output:
C:\c>a
1234567
67452301

I do not like the g++ way, lol. visual studio used to let you just put variables in directly, eg mov eax, x; <--- like that
it was much easier. It may still use this format (?). I dunno, as I said, this was my first assembly attempt in many years.

I picked CRC because its simple and you can indeed beat the machine at its game in assembly. I didn't know about a contest, though.

your problem may be that some compiler versions of g++, like mine, want %% on registers instead of single %. Those are the little things I said were issues across compilers :(
Last edited on
I tried the sample above again with %% and still no go. And it wanted single %s on those commands, but doubles when I did mine. I am not sure what the % vs %% thing means right now -- the trouble with imitation instead of properly looking up what the stuff means...
it hates the label statement and I am out of patience trying to fix it today.
Last edited on
First, let me point out that using GCC to learn inline assembly is a significant disadvantage.

This is because GCC introduces a layer to be learned on top of the underlying subject. The underlying subject, for a Windows target, is x86_64 assembler (and/or possibly 32 bit x86 if you're writing such targets).

The layer GCC puts on top of that is called the AT&T syntax (which makes every Intel word for an assembler instruction an AT&T alternative).

It is possible to instruct GCC to use the Intel dialect, but it is still a strange way to code assembler, and a way that only works on GCC.

I'm going to make this a serious recommendation - move to Visual Studio. It's free, it is for Windows, you can install it with Clang (for better C++ compliance, though VS is quite decent up to C++17).

I'll put it this way - I so much despise the AT&T dialect, and GCC's approach to inline assembler, that I'm not willing to help anyone learning both at once.

If you're going to make sense of inline assembler on Windows, you must, absolutely must use Visual Studio.

@jonnin's post is an example as to why this is important.

Now, consider this small MASM example taken from Microsoft's documentation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
; POWER.ASM
; Compute the power of an integer
;
       PUBLIC _power2
_TEXT SEGMENT WORD PUBLIC 'CODE'
_power2 PROC

        push ebp        ; Save EBP
        mov ebp, esp    ; Move ESP into EBP so we can refer
                        ;   to arguments on the stack
        mov eax, [ebp+4] ; Get first argument
        mov ecx, [ebp+6] ; Get second argument
        shl eax, cl     ; EAX = EAX * ( 2 ^ CL )
        pop ebp         ; Restore EBP
        ret             ; Return with sum in EAX

_power2 ENDP
_TEXT   ENDS
        END


Now, compare that to this C inline assembler using Visual Studio


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Power2_inline_asm.c
// compile with: /EHsc
// processor: x86

#include <stdio.h>

int power2( int num, int power );

int main( void )
{
    printf_s( "3 times 2 to the power of 5 is %d\n", \
              power2( 3, 5) );
}
int power2( int num, int power )
{
   __asm
   {
      mov eax, num    ; Get first argument
      mov ecx, power  ; Get second argument
      shl eax, cl     ; EAX = EAX * ( 2 to the power of CL )
   }
   // Return with result in EAX
}


It may take a while to compare, but notice where in the MASM example there is a "mov eax..." instruction, a second instruction, mov ecx..., and then a shl eax.... the same sequence you see in the C inline assembly example. They are the same function, multiplication by a power of 2.

...notice how they look nearly the same

That doesn't work that way in GCC, and it will confuse and frustrate your ability to learn inline assembler.

Move to Visual Studio. That isn't a suggestion at this point. If you want more help, it would be a requirement for most of us.

Once you know inline assembler using Visual Studio, you can then consider adapting to GCC's horrible mess of a method, because at that point you have only one thing to learn (GCC's method), and the rest will be more recognizable.

The Visual Studio (Microsoft) approach to inline assembler so much resembles regular assembler, that you can almost intermix the two freely - while it also matches what you might read on x86/64 assembler from all other sources.

That won't work with GCC - they use slightly different keywords, and a mess of a syntax for wrapping the stuff up.


It is also worth noting that when you use assembler, inline or not, you're playing with fire. You will get burned, and it will be confusing for a while. You are working at a level where instructions execute in the billions per second speed. You are in rather direct control of the CPU at the hardware level, though still subject to the restrictions placed on you by the operating system. Anything one can screw up in C can be screwed up on a whole new level in assembler. Debugging is generally quite more of a pain.

You are turning to the dark side. It is a pathway to the unnatural. :)
Last edited on
jonnin: yes that code now works fine...
now i need learn more about it.. so what tutorial you advice me?

Niccolo: yes you have right... but, in these case, i'm using GCC... sorry
I gave you 2 links to work on above, one on asm commands and one on g++ gibberish. Between them you should be able to start doing some small things. Keep it to < 5 lines + variables for a while, start really slowly with this stuff...
yes jonnin: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
let me ask you more 1 thing: is better, too, see an ASM tutorial?
Yes, I think you will want to look over ASM coding or at least go through the ASM keywords and commands and how the side effects (eg flags and command result registers) etc work. You have to know what the instructions are and what they do, or you won't have much luck writing anything useful. And you need to see some code examples and tutorials to see how to string stuff together correctly. But I don't know what tutorial to point you to ... you will just have to cruise the web to find one you like.

There are multiple oddball instructions that do cool things that simply can't be done as efficiently in c++ like the bswap I gave. the HTONL library command may know on your compiler to swap out to bswap in assembly but if you did it by hand with bitwise logic it would never figure that out. And the templated swap will never use registers because its set up for objects, but an integer register swapper or stack push pop swap is going to blow that away unless they wrote specialized versions. Seeing what all those instructions can DO lets you find some weird shortcuts that are just amazingly fast. On the flipside, beating the compiler is getting harder and harder for most code.
Last edited on
correct me 1 thing: from these Assembler tutorial: https://www.tutorialspoint.com/assembly_programming/assembly_environment_setup.htm
and see these text:
Local Environment Setup
Assembly language is dependent upon the instruction set and the architecture of the processor. In this tutorial, we focus on Intel-32 processors like Pentium. To follow this tutorial, you will need −

An IBM PC or any equivalent compatible computer
A copy of Linux operating system
A copy of NASM assembler program
There are many good assembler programs, such as −

Microsoft Assembler (MASM)
Borland Turbo Assembler (TASM)
The GNU assembler (GAS)

now the C Inline Assembler is ASM or GAS?
in g++ its GAS, I would think. I don't know, this is me applying common sense to give you a guess. TASM is likely dead, not 100% sure but I have not heard 'borland' in decades. MASM is visual studio / microsoft of course. So that leaves Gas :)

I have no idea what that site is going on about. you can use the unix tools he lists on windows, you don't need to install linux for them.
If you're doing inline assembler statements, you don't need a separate assembler.
See the following article for an example of inline assembler in a C/C++ program.
https://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C

A separate assembler is only required if you're going to create an entire module by itself and then link it into a larger program (or possibly just execute it by itself).


AbstractionAnon: thank you so much.
let me ask anotherthing: why they, always, use 'printf' instead Assembler code for output?
why they, always, use 'printf' instead Assembler code for output?

Ever tried to do output in assembler?
Every bit of formatting and I/O must be done by you.
even doing that in c++ without using the library is hard. Try converting an integer to a string for output efficiently. (printf, cout, etc are actually extremely slow at this, and you can blow them to shreds with your own code, but its a lot of work).

Ive got a C one for 0 to 999 for a high speed project that is about 3 pages of code, it cut a ton of time off the program but its a mess.
thank you so much to all for all... thank you
Topic archived. No new replies allowed.
Pages: 12