1

i have to print an statement based on whther a value is positive, negative or equal to zero in c++, but the logic of the decition has to be in assembler. the logic i have alredy works but when i try to move the string value to the string dedicated to the ouput i get a wrong operand type error.

#include <iostream>
#include <string>
int main(){
    double r;
    std::string mNeg="r its negative, r = ",
                mPos="r its positive, r = ",
                mEqu="r its equal to zero,     r = ",
                mOutput;
    _asm{
          .
          .
          .
          .
      calculate r
          .
          .
          .
          .
     ;comparison
        equal:
            fld r
            ftst
            fstsw ax
            fwait
            sahf
            ja Jpos
            jb Jneg        
            mov mOutput, mEqu             ;<---this is where the error happens
            jmp fin
        Jpos:
            mov mOutput, mPos             ;<---this is where the error happens
            jmp fin
        Jneg:
            mov mOutput, mNeg             ;<---this is where the error happens
        fin:
    }
    std::cout<<mOutput<<r;                ;<---here i'm supposed to print the output
}
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
DGarciaBl
  • 31
  • 2
  • 3
    `std::string` is a C++ class. Only a C++ compiler knows what is the right code to do this. You will be surprised to learn that "moving" one `std::string` object to another is not just a single assembly instruction. C++ is not that simple. I would estimate, a ballpark amount of a dozen assembly instructions to do that, to call `std::string::operator=` with all the right parameters. And if you simply can't call the operator function itself, and do ***everything*** in assembly, make that 30-40 assembly instructions. Can you explain why, exactly, "logic of the decition has to be in assembler"? – Sam Varshavchik Sep 04 '21 at 22:40
  • its an assignment and the proffesor said to do it all in assembler, only the definition of the variables, input and output is to be done in c++ code. i tryed it copying the string but i get other error saying im infryinging access ''' mov esi, 0 mov ecx, 32 L1: mov al, mEqu[esi] mov msalida[esi], al inc esi loop L1 ''' – DGarciaBl Sep 04 '21 at 22:44
  • 2
    So don't use std::string. `char *outmsg;` might be useful, with global / static `char msgPos[] = "...";` and so on so you have named asm symbols you can use with `mov outmsg, OFFSET msgPos`. – Peter Cordes Sep 04 '21 at 23:08
  • Also note that you don't need `fwait`. – Peter Cordes Sep 04 '21 at 23:11
  • 2
    I concur that this should be using plain chars, and not C++ classes. It doesn't make sense to do so. – Sam Varshavchik Sep 04 '21 at 23:18
  • Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. – Community Sep 09 '21 at 11:23
  • Just write the same code in pure C++, without inline assembly and then disassemble, copy and paste the assembly code into your inline assembly block and baffle your professor :) – BitTickler Sep 11 '21 at 00:08

1 Answers1

2

I finally did it this way. I made the strings into an array, and the decition is just the index of the string in the array.

#include <iostream>
#include <string>
int main(){
    int d;
    double r;
    std::string mOutput[3]={"r its equal to zero,     r = ","r its positive, r = ","r its negative, r = "}; ;<-----Change
    _asm{
          .
          .
          .
          .
      calculate r
          .
          .
          .
          .
     ;comparison
        equal:
            fld r
            ftst
            fstsw ax
            fwait
            sahf
            ja Jpos
            jb Jneg        
            mov d, 0             ;<---change
            jmp fin
        Jpos:
            mov d, 1             ;<---change
            jmp fin
        Jneg:
            mov d, 2             ;<---change
        fin:
    }
    std::cout<<mOutput[d]<<r;                ;<---print the output
}
Pierre.Vriens
  • 2,117
  • 75
  • 29
  • 42
DGarciaBl
  • 31
  • 2
  • Yup, that works. You might want to add the 4th possibility of what a float can be, NaN. (Check for that with `jp nan`. [x86 assembler: floating point compare](https://stackoverflow.com/q/7057501)) – Peter Cordes Sep 10 '21 at 23:52
  • Also, your code leaves a value on the x87 stack. You should have an `fstp st(0)` somewhere after the `ftst` to pop it and leave the x87 stack empty. http://www.ray.masmcode.com/tutorial/fpuchap1.htm. If you want to learn the mostly-obsolete legacy x87 FPU instead of modern SSE for scalar math, use it properly. – Peter Cordes Sep 10 '21 at 23:54