flat assembler
Message board for the users of flat assembler.

Index > Main > Where to start?

Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
Author
Thread Post new topic Reply to topic
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 30 Mar 2012, 17:38
Code:
prompt    db    "Enter a number: ", 0
squareMsg db    "Square of the input is: ", 0
numFormat db    "%u", 0

;============================================================================
section '.bss' data readable writeable

__input    rd    1

;============================================================================
section '.text' code readable executable

        start:
          ccall    [printf], prompt

          ;=== MULTIPLICATION =====================
          ccall    [getchar], __input             ; Get input
          mov      eax, __input                   ; Move input into EAX
          imul     eax                            ; Multiply EAX by itself
          ccall    [printf], squareMsg            ; Print a message
          mov      [__input], eax                 ; Move the result
          ccall    [printf], numFormat, [__input] ; Print out the result

          ;========================================

          ccall    [getchar]
          ccall    [getchar]
          invoke   ExitProcess, 0
    


This just prints nonsense (4202496). When I use brackets around __input, it always prints out "24". Is there a problem with the imul code, or is my printf at fault? Thanks a lot for help
Post 30 Mar 2012, 17:38
View user's profile Send private message Reply with quote
dancho



Joined: 06 Mar 2011
Posts: 74
dancho 30 Mar 2012, 18:01
getchar reads one ( 1 ) character from stdin,
use gets or gets_s or fgets for reading a string,
then something from ato* family to convert string to number...
something like this:
Code:
format PE console 5.0
entry cmain
include 'win32axp.inc'

section '.text' code readable executable
cmain:
                
            cinvoke printf,<'Enter a number :',0>
           cinvoke gets,buffer
         cinvoke atoi,buffer
         mov [num],eax
               cinvoke printf,<'Number is %u',0>,[num]
                     
            invoke ExitProcess,0
                
            
section '.data' data readable writeable
               num     rd 1
                buffer  rb 32
               
section '.idata' import data readable
 library kernel32,'kernel32.dll',\
                  msvcrt,'msvcrt.dll'
             
    include 'api\kernel32.inc'
       include 'api\msvcrt.inc'
    


and you will have to use some debugger ( ollydbg is popular ) to see how exactly fasm do his magic and compile this code into exe file...
Post 30 Mar 2012, 18:01
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1509
Location: Toronto, Canada
AsmGuru62 30 Mar 2012, 19:07
I think if you want multiply EAX by itself it would be: "IMUL EAX,EAX".
Post 30 Mar 2012, 19:07
View user's profile Send private message Send e-mail Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek 30 Mar 2012, 20:36
dancho wrote:
getchar reads one ( 1 ) character from stdin,
use gets or gets_s or fgets for reading a string,
then something from ato* family to convert string to number...
something like this:
Code:
format PE console 5.0
entry cmain
include 'win32axp.inc'

...
          
    include 'api\kernel32.inc'
       include 'api\msvcrt.inc'
    


and you will have to use some debugger ( ollydbg is popular ) to see how exactly fasm do his magic and compile this code into exe file...


Unable to compile for some reason, tried different variants, but th error persists. So sad.

Code:
C:\Users\gilyazov\Documents\Programs\fasm\INCLUDE/api_ext\msvcrt.inc [1]:
import  msvcrt,\
C:\Users\gilyazov\Documents\Programs\fasm\INCLUDE/macro/import32.inc [31] import [5]:
     if used label
error: reserved word used as symbol.
    
Post 30 Mar 2012, 20:36
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek 30 Mar 2012, 21:04
This one works:
Code:

format PE console
entry cmain
include 'win32axp.inc'

cmain:
    cinvoke printf,<'Enter a number :',0> 
  cinvoke gets,buffer 
        cinvoke atoi,buffer 
        mov [num],eax 
      cinvoke printf,<'Number is %u',0>,[num] 
    ;cinvoke        exit,0
      invoke  ExitProcess,0

section '.data' data readable writeable
      buffer  rb      32
  num     rd      1

section '.idata' data import readable
  library msvcrt,'MSVCRT.DLL',\
      kernel32,'KERNEL32.DLL'

  import msvcrt,\
 printf,'printf',\
        exit,'_exit',\
   gets,'gets',\
    atoi,'atoi'

  import kernel32,\
   ExitProcess,'ExitProcess'

    
Post 30 Mar 2012, 21:04
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 31 Mar 2012, 07:13
Okay, I will play with this for a long time, just tell me one thing, bzdashek. Why did you put buffer and num into .data and not .bss? Shouldn't uninitialized variables go into .bss? Thanks a lot


Last edited by Inagawa on 31 Mar 2012, 13:26; edited 2 times in total
Post 31 Mar 2012, 07:13
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek 31 Mar 2012, 11:35
Inagawa wrote:
Okay, I will play with this for a long time, just tell me one thing, bzdashek. Why did you put buffer and num into .data and not .bss? Shouldn't unitialized values go into .bss? Thanks a lot

Inagawa, douzo yoroshiku onegaishimasu.

I put it there for no reason, since I was unaware about this convention - placing uninit data in .bss. For operating system it's no difference. You can name your segments whatever you like, since name doesn't matter. I believe it's just a good style of programming to name them '.code', '.data', '.bss' etc. Someone correct me if I'm mistaken.
Post 31 Mar 2012, 11:35
View user's profile Send private message Reply with quote
dancho



Joined: 06 Mar 2011
Posts: 74
dancho 31 Mar 2012, 17:29
hmm opera cache is playing games with me,
sry mods plz delete...
Post 31 Mar 2012, 17:29
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 01 Apr 2012, 06:42
Haha I posted a program, but I decided to expand it and learn more before writing and asking stuff here again. So maybe you caught a glimpse before I deleted it.
Post 01 Apr 2012, 06:42
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 01 Apr 2012, 16:08
Code:
format PE console
entry cmain

include 'win32axp.inc'

;=============================================================================
section '.data' data readable writeable
  __separatorMsg   db      '=========================================', 10, 0
  __promptMsg      db      '> Enter a number: ', 0
  __resultMsg      db      '=> Result is %i', 10, 0
  __addMsg         db      '> Addition: (0 + Input)', 10, 0
  __subMsg         db      '> Subtraction: (100 - Input)', 10, 0
  __mulMsg         db      '> Multiplication: (Input * Input)', 10, 0
  __divMsg         db      '> Division: (100 / Input)', 10, 0
  __negMsg         db      '> Negation: (Input * (-1))', 10, 0
  __64addMsg       db      '> 64bit Addition (Input + 2147483647)', 10, 0
  __64subMsg       db      '> 64bit Subtraction (2147483647 - Input)', 10, 0
  __jumpMsg        db      '> Jumping (Input >= 50 =< Input)', 10, 0
  __jumpGMsg       db      '=> More than 50.', 10, 0
  __jumpLMsg       db      '=> Less than 50.', 10, 0
  __jumpEMsg       db      '=> Equal to 50.', 10, 0
  __loopMsg        db      '> Looping (Msg * Input)', 10, 0
  __primeMsg       db      '> Finding prime numbers', 10, 0
  __shiftMsg       db      '> Shifting (Input * 4, Input / 4)', 10, 0
  __shiftLMsg      db      '=> Shifted Left by 2: %i', 10, 0
  __shiftRMsg      db      '=> Shifted Right by 2: %i', 10, 0
  __rotationMsg    db      '> Rotations (Input * 4, Input / 4)', 10, 0
  __subprogMsg     db      '> Subprogram', 10, 0
  __subprogResMsg  db      '=> Subprogram returned.', 10, 0

;=============================================================================
section '.bss' data readable writeable
  __buffer      rb      32
  __input       rd      1

;=============================================================================
section '.text' code readable executable

cmain:
  ;=== GET INPUT =================================
  cinvoke      printf, __promptMsg                ; Print out prompt
  cinvoke      gets, __buffer                     ; Read string into buffer
  cinvoke      atoi, __buffer                     ; Store converted into EAX
  mov          [__input], eax                     ; Move EAX to input
  cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== ADDITION ==================================
  cinvoke      printf, __addMsg                   ; Print out the message
  xor          eax, eax                           ; Zero out EAX
  add          eax, [__input]                     ; Add input to EAX
  cinvoke      printf, __resultMsg, eax           ; Print out the result
  cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== SUBTRACTION ===============================
  cinvoke      printf, __subMsg                   ; Print out the message
  mov          eax, 100                           ; Init EAX with 100
  sub          eax, [__input]                     ; Add input to EAX
  cinvoke      printf, __resultMsg, eax           ; Print out the result
  cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== MULTIPLICATION ============================
  cinvoke      printf, __mulMsg                   ; Print out the message
  mov          eax, [__input]                     ; Load the input into EAX
  imul         eax                                ; Multiply EAX by itself
  cinvoke      printf, __resultMsg, eax           ; Print out the result
  cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== DIVISION ==================================
  cinvoke      printf, __divMsg                   ; Print out the message
  mov          ecx, [__input]                     ; Load the input into EAX
  cdq                                             ; Extend EAX into EDX:EAX
  mov          eax, 100                           ; Init EAX with 100
  idiv         ecx                                ; Divide EAX by ECX
  cinvoke      printf, __resultMsg, eax           ; Print out the result
  cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== NEGATION ==================================
  cinvoke      printf, __negMsg                   ; Print out the message
  mov          eax, [__input]                     ; Load the input into EAX
  neg          eax                                ; Negate EAX
  cinvoke      printf, __resultMsg, eax           ; Print out the result
  cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== 64bit ADDITION ============================
  ;cinvoke      printf, __64addMsg                 ; Print out the message
  ;mov          eax, 2147483647                    ; Init EAX with 2147483647
  ;mov          ecx, [__input]                     ; Init ECX with input
  ;add          eax, ecx                           ; Add the lower half
  ;xor          edx, edx                           ; Zero out EDX
  ;xor          ebx, ebx                           ; Zero out EBX
  ;adc          edx, ebx                           ; Add the upper half
  ;cinvoke      printf, __resultMsg, edx:eax       ; Print out the result
  ;cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== JUMPS =====================================
  cinvoke      printf, __jumpMsg                  ; Print out the message
  mov          eax, [__input]                     ; Move input to EAX
  cmp          eax, 50                            ; Compare EAX to 50
  jg           more50                             ; Jump if EAX > 50
  jl           less50                             ; Jump if EAX < 50
  je           equal50                            ; Jump if EAX == 50

more50:
  cinvoke      printf, __jumpGMsg                 ; Print out result
  jmp          jumpEnd                            ; Skip the rest

less50:
  cinvoke      printf, __jumpLMsg                 ; Print out result
  jmp          jumpEnd                            ; Skip the rest

equal50:
  cinvoke      printf, __jumpEMsg                 ; Print out result

jumpEnd:
  cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== LOOPING ===================================
  ;cinvoke      printf, __loopMsg                  ; Print out the message
  ;mov          ecx, [__input]                     ; Init ECX with input

;loopStart:
  ;cinvoke      printf, <'Hello', 10, 0>           ; DOES NOT WORK, BUT WHY?
  ;loop         loopStart                          ; Loopback until ECX == 0

  ;cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== FIND PRIME NUMBERS ========================
  ;cinvoke      printf, __primeMsg                 ; Print out the message
  ;mov          eax, 2                             ; Init EAX with 2
  ;cinvoke      printf, __resultMsg, eax           ; Special case
  ;mov          eax, 3                             ; Init EAX with 3
  ;cinvoke      printf, __resultMsg, eax           ; Special case
  ;mov          edx, 5                             ; First guess at a prime

;while_limit:
  ;mov          eax, edx                           ; Move the guess to EAX
  ;cmp          eax, [__input]                     ; Compare guess to limit
  ;jnbe         end_while_limit                    ; If out-of-bounds, jump
  ;mov          ebx, 3                             ; Move factor into EBX

;while_factor:
  ;mov          eax, ebx                           ; Move the factor to EAX
  ;mul          eax                                ; Multiply EAX by itself
  ;jo           end_while_limit                    ; Result > 32bit
  ;cmp          eax, edx                           ; Compare factor to guess
  ;jnb          end_while_factor                   ; Jump if factor^2 > guess
  ;mov          eax, edx                           ; Move guess into EAX
  ;push         edx                                ; Push EDX no stack
  ;xor          edx, edx                           ; Zero out EDX
  ;div          ebx                                ; Divide EDX:EAX by EBX
  ;cmp          edx, 0                             ; Compare EDX to zero
  ;je           end_while_factor                   ; Jump if EDX == 0
  ;add          ebx, 2                             ; Add 2 to factor
  ;jmp          while_factor                       ; Repeat the loop

;end_while_factor:
  ;je           end_if                             ; Jump if guess/factor == 0
  ;pop          edx                                ; Take back guess from stack
  ;mov          eax, edx                           ; Move guess into EAX

;end_if:
  ;add          edx, 2                             ; Add 2 to EDX
  ;jmp          while_limit                        ; Jump back

;end_while_limit:
  ;cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== SHIFTS ====================================
  cinvoke      printf, __shiftMsg                 ; Print out the message
  mov          eax, [__input]                     ; Load the input into EAX
  push         eax                                ; Push EAX into stack
  sal          eax, 2                             ; Shift EAX 2 bits left
  cinvoke      printf, __shiftLMsg, eax           ; Print out result of SAL
  pop          eax                                ; Pop EAX from stack
  sar          eax, 2                             ; Shift EAX 2 bits right
  cinvoke      printf, __shiftRMsg, eax           ; Print out result of SAR
  cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== ROTATIONS =================================
  cinvoke      printf, __rotationMsg              ; Print out the message
  mov          eax, [__input]                     ; Load the input into EAX
  push         eax                                ; Push EAX into stack
  rol          eax, 2                             ; Rotate EAX 2 bits left
  cinvoke      printf, __shiftLMsg, eax           ; Print out result of SAL
  pop          eax                                ; Pop EAX from stack
  ror          eax, 2                             ; Rotate EAX 2 bits right
  cinvoke      printf, __shiftRMsg, eax           ; Print out result of SAR
  cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== SUBPROGRAMS ===============================
  cinvoke      printf, __subprogMsg               ; Print out the message
  mov          eax, [__input]                     ; Load the input into EAX
  call         printResult                        ; Call printResult

  ;=== LEAVE CONSOLE OPEN ========================
  cinvoke      getchar                            ; Leave console open
  cinvoke      exit, 0                            ; C-Style exit ??

;============================================================================
section '.text' code executable readable

;=== PRINT RESULT SUBPROGRAM =====================
printResult:
  push         ebp                                ; Store EBP
  mov          ebp, esp                           ; Init EBP with ESP
  cinvoke      printf, __subprogResMsg            ; Print out the result
  mov          esp, ebp                           ; Restore ESP
  pop          ebp                                ; Restore EBP
  ret                                             ; Return

;=============================================================================
section '.idata' data import readable
  library msvcrt,'MSVCRT.DLL',\
        kernel32,'KERNEL32.DLL'

  import msvcrt,\
        printf,'printf',\
        getchar,'_fgetchar',\
        exit,'_exit',\
        gets,'gets',\
        atoi,'atoi',\
        atof,'atof'

  import kernel32,\
        ExitProcess,'ExitProcess'    


Okay, this is the finished version of my 'programming journey' (so far, ofc). I am on the page 87, about to tackle multi-module programs and the code so far is so long that it would hinder me, so I'll start fresh. I've learned a few things, but there is much that confuses me (the commented-out code). I know the 64bit addition is completely wrong, so that aside, what about the looping?
I know that printf actually pushes the address of the message and then calls something to print it out, but that should only modify EAX, no? (My god how long it took me to find why my EAX register had weird values after printing out something Very Happy) The loop goes on forever, refusing to terminate if I try to print 'Hello' X times. I know printf is at fault, since removing it safely reruns the loop only finite amount of times.

About subprograms. I had to move my function body into a segment of its own to avoid having it 'automatically' called without invocation - is this a normal practice? (Maybe it is a premature question, as I'll probably get an answer in the multi-module part of the book.) Anyway, thanks for any advice I might get and sorry for the long post/code Smile
Post 01 Apr 2012, 16:08
View user's profile Send private message Reply with quote
ProphetOfDoom



Joined: 08 Aug 2008
Posts: 120
Location: UK
ProphetOfDoom 02 Apr 2012, 00:37
I can't run your code as I'm not using Windows but I glanced over it quickly. The looping problem is probably due to the printf function overwriting the ecx register. There are IIRC three registers on x86 known as "scratch" registers - they are not guaranteed to remain the same across function calls. They are eax, ecx, and edx. So you could fix the problem by using another register as your loop counter such as ebx, combined with a "jnz" instruction. Alternatively you could "push ecx" before your function call and "pop ecx" afterwards to restore its value.

About the putting functions in sections thing... no, you wouldn't normally put each function in its own section. Just be aware that execution will always "fall through" to the next instruction. If you have a call to "exit" followed by your own function, the function won't be executed. I don't know if fasm merges sections with the same name, it may do (I think most linkers do), but the result you got from having the function in its own section is probably accidental and not the way to do it.
Post 02 Apr 2012, 00:37
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 02 Apr 2012, 08:43
I see. I was stupid to think that printf does not modify ECX. After all, it has to count a loop to print out the individual characters.

I know that execution falls through, but I have to separate functions into their segments, or I would have to use a redundant jump over the function body.

If I call FUNC from CODE, once the FUNC returns, it will continue it's execution over FUNC without actually being invoked, trampling over data and then the RET instruction will actually end the program itself, closing the console. This is precisely what happened to me. What is the solution, then?

;==CODE==
;==FUNC==
Post 02 Apr 2012, 08:43
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek 02 Apr 2012, 09:59
On my machine runs OK. But what do you mean by 'automatically called'? Since procedure is located after exit() call, it won't run unless it's called manually
Post 02 Apr 2012, 09:59
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 02 Apr 2012, 12:58
It is now. But before that the code looked like this.

Code:
;=== SUBPROGRAMS ===============================
  cinvoke      printf, __subprogMsg               ; Print out the message
  mov          eax, [__input]                     ; Load the input into EAX
  call         printResult                        ; Call printResult

  printResult:
  push         ebp                                ; Store EBP
  mov          ebp, esp                           ; Init EBP with ESP
  cinvoke      printf, __subprogResMsg            ; Print out the result
  mov          esp, ebp                           ; Restore ESP
  pop          ebp                                ; Restore EBP
  ret                                             ; Return

  ;=== LEAVE CONSOLE OPEN ========================
  cinvoke      getchar                            ; Leave console open
  cinvoke      exit, 0                            ; C-Style exit ??     


And once the printResult returned, the execution fell into the printResult again, since it was placed below it. And since Prophet tells me "placing every function into its own segment is wrong", I have no idea what to actually do other than place a jmp after the call to printResult, but that would be unsightly.. Confused
Post 02 Apr 2012, 12:58
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 02 Apr 2012, 15:18
Haha anyway, forget the previous problems, look at what I programmed. I am proud of myself, since I didn't use any tutorials, only my knowledge so far. I will expand on this (sort numbers from highest to lowest, compute median, etc.) later. Smile

Code:
format PE console
entry cmain

include 'win32axp.inc'

;=============================================================================
section '.data' data readable writeable
  __separatorMsg   db      '==========================================================', 10, 0
  __promptMsg      db      '> Enter a number (negative ends input): ', 0
  __resultMsg      db      '=> %i', 10, 0
  __arrayMsg       db      '> Here is the content of the Array: ',10, 0


;=============================================================================
section '.bss' data readable writeable
  __buffer      rb      32
  __array       rd      64

;=============================================================================
section '.text' code readable executable

cmain:
  ;=== GET INPUT =================================
  xor          ebx, ebx                           ; Zero out EBX

inputLoop:
  cinvoke      printf, __promptMsg                ; Print out prompt
  cinvoke      gets, __buffer                     ; Get string into buffer
  cinvoke      atoi, __buffer                     ; Convert string to number
  cmp          eax, 0                             ; Compare EAX(input) with 0
  jl           endInputLoop                       ; Terminate if EAX(input) < 0
  mov          [__array+ebx], eax                 ; Store the input in array
  add          ebx, 4                             ; Increase the pointer by 4
  cmp          eax, 0                             ; Compare EAX(input) to 0
  jge          inputLoop                          ; Repeat if EAX(input) >= 0

endInputLoop:
  cinvoke      printf, __separatorMsg             ; Print out the separator
  cinvoke      printf, __arrayMsg                 ; Print out the message
  mov          ecx, 4                             ; Init divisor(ECX) with 4
  mov          eax, ebx                           ; Init EAX(dividend) with EBX
  cdq                                             ; Extend EAX into EDX:EAX
  idiv         ecx                                ; EAX / 4 = number of arguments
  mov          ecx, eax                           ; Move the number into ECX
  mov          ebx, __array                       ; Init EBX with the adress of array

loopArr:
  push         ecx                                ; Store ECX
  cinvoke      printf, __resultMsg, DWORD [ebx]   ; Print out the array at EBX
  add          ebx, 4                             ; Increase EBX by 4 bytes
  pop          ecx                                ; Restore ECX
  loop         loopArr                            ; Repeat
  cinvoke      printf, __separatorMsg             ; Print out the separator

  ;=== LEAVE CONSOLE OPEN ========================
  cinvoke      getchar                            ; Leave console open
  cinvoke      exit, 0                            ; C-Style exit ??

;=============================================================================
section '.idata' data import readable
  library msvcrt,'MSVCRT.DLL',\
        kernel32,'KERNEL32.DLL'

  import msvcrt,\
        printf,'printf',\
        getchar,'_fgetchar',\
        exit,'_exit',\
        gets,'gets',\
        atoi,'atoi',\
        atof,'atof'

  import kernel32,\
        ExitProcess,'ExitProcess'    
Post 02 Apr 2012, 15:18
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 05 Apr 2012, 15:40
Okay, so here am I again. This time about floating point multiplication.

Code:
  ;=== FLOAT MULTIPLICATION SUBROUTINE ===========
%FMul%:
  push          ebp
  lea           ebp, [esp+4]
  sub           esp, 0

  cinvoke       printf, __separatorMsg
  cinvoke       printf, __fmulMsg

  fild          DWORD[ebp+8]                     ; S: A
  fild          DWORD[ebp+4]                     ; S: B, A
  fimul         st1                              ; S: AB
  fistp         [__output]
  cinvoke       printf, __mulResultMsg, DWORD[ebp+8], DWORD[ebp+4], [__output]

  lea           esp, [ebp-4]
  pop           ebp
  ret
    


For some reason the fimul st1(or fmul, fmulp) is giving me an error, why is that? I haven't been able to make it work in any way.
Post 05 Apr 2012, 15:40
View user's profile Send private message Reply with quote
gunblade



Joined: 19 Feb 2004
Posts: 209
gunblade 05 Apr 2012, 16:44
Did you remember to execute the finit instruction somewhere at the start of your code before you execute that subroutine? That could be the issue..
Post 05 Apr 2012, 16:44
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1509
Location: Toronto, Canada
AsmGuru62 05 Apr 2012, 16:59
FMUL ST1 -- not FIMUL ST1.
ST1 is not Integer.

Also, FMULP is better here, because when this function returns FPU will have ST0 in a non-empty state. It may cause exceptions later in code.

A simple example would be to call that function in a loop for 8 times -- somewhere after that - the FPU will give an exception on load a value into ST0, because all 8 FPU registers will be busy with values.
Post 05 Apr 2012, 16:59
View user's profile Send private message Send e-mail Reply with quote
gunblade



Joined: 19 Feb 2004
Posts: 209
gunblade 05 Apr 2012, 17:15
Well spotted, didnt see the i Smile - but he did say that he tried fmul and fmulp as well.. hence why i thought it might be the lack of initialisation..
Post 05 Apr 2012, 17:15
View user's profile Send private message Reply with quote
gunblade



Joined: 19 Feb 2004
Posts: 209
gunblade 05 Apr 2012, 17:21
Ah, just tried it in my own code. You mean it doesnt assemble? fasm gives you an error? because it does for me. You cant do fimul st1, as AsmGuru62 says.. What you should use is just:

Code:
fmulp    


No parameters.. that'll carry out st1 = st0*st1 then pop the stack

Not sure if finit makes a difference, my code still seems to run whether i finit or not.. but I would do it to be safe..

If you REALLY wanted to specify parameter, then you have to specify both registers, such as:

Code:
fmulp st1,st0    
Post 05 Apr 2012, 17:21
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.