News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Converting from Celsius to Fahrenheit

Started by RKC, April 29, 2019, 06:14:14 AM

Previous topic - Next topic

RKC

I am tasked at writing a program in C that uses external modules from from a .asm file. I do not have a background in assembly, mainly cpp. However, I managed to get so far into my program using a book by kip Irvine, YouTube videos, etc. All of my code works up to the c2f function, which is where I start having the problems. The entire code is attached in the two separate files, but a code snippet from the .asm file c2f: is below. Basically as soon as it gets to the mov ebx, 5 it calls a segmentation fault core dumped. I tried using the edx register and this causes a floating point core dumped in my terminal. I've literally exhausted all options and I ran across this forum by chance in my search for an answer. Can somebody please help me, rubber ducky hasn't helped.

c2f:
  mov eax, [esp+4]
  imul eax,9
  add eax,160
  mov ebx, 5
  div ebx

  ret

Edit: And I know it would be nice to just have the fix for this, but the why is what's driving me nuts. Even though this is just one assignment and the class is not over assembly, I would like to understand why. I know that when you divide by something the overflow goes into edx, but I don't know why it's causing the errors that it causes. Any help or suggestions is appreciated.

aw27


RKC

If floats are returned in STO, then how would the ret function work?

c2f:
  mov eax, [esp+4]
  imul eax,9
  add eax,160
  ;mov ebx, 5
  ;div ebx

  ret

Noticed the two lines commented out, if I type in 20 in the function, it returns 340. I know that the function is getting that far so the error is in mov ebx, 5 and div ebx.

aw27

It is NOT an IF, they do indeed return in ST0. Don't doubt what people here tells you unless you can present evidence.

So, what you have to do is convert the integer to float before the RET. Isn't it obvious?
If you don't want to do it, make the C function wait for an integer.


jj2007

You get an exception with div ebx because edx is not zero. Use the cdq instruction:
c2f:
  mov eax, [esp+4]
  imul eax,9
  add eax,160
  mov ebx, 5
  cdq
  div ebx
  retn 4


Btw which assember are you using? It's definitely not MASM 8)

RKC

Quote from: AW on April 29, 2019, 06:49:55 AM
It is NOT an IF, they do indeed return in ST0. Don't doubt what people here tells you unless you can present evidence.

So, what you have to do is convert the integer to float before the RET. Isn't it obvious?
If you don't want to do it, make the C function wait for an integer.

Ok first thing,  I was only asking out of clarification because I was only handed a crappy little one liner that isn't blatantly obvious to somebody that hasn't seen this before this week. Second off, no reason to be such a prick about it. While some things may seem nontrivial to you, it may not be so to somebody that just got forced to learn an abundance of the language in a short amount of time. I simply was asking for clarification, I even posted the snippet with what I had commented out and what I had returned up until that point to further clarify where I had gotten. If that is how you react to a clarity question with an explanation of debugging I sincerely hope that you are not a supervisor anywhere because I would really hate to work for your company, or with you for that matter. While I appreciate your reply, I wasn't doubting what you were telling me, maybe the response came off as such, I don't know so I apologize if it did.

RKC

Quote from: jj2007 on April 29, 2019, 06:54:46 AM
You get an exception with div ebx because edx is not zero. Use the cdq instruction:
c2f:
  mov eax, [esp+4]
  imul eax,9
  add eax,160
  mov ebx, 5
  cdq
  div ebx
  retn 4


Btw which assember are you using? It's definitely not MASM 8)

Thanks for the reply bud! I'll have to look up cdq. I thought it was MASM from what I had looked up. I am taking a systems programming class so I am doing all of this in a dual boot ubuntu system. I'm running straight off the terminal using makefile with my folder. We had been doing nothing but C programming up until this past week. I thought it was assembly for x86 processors  :badgrin: oops! Honestly most of my assembly language experience is in MIPS.

I'm still getting a core dumped, but I'm looking into it. Thanks for pointing me in the right direction!

jj2007

cdq sign-extends eax to edx: if eax is positive, edx will be set to zero, if eax is negative, edx will be -1.

Here are two variants of your code, both return the result in eax and in ST(0):

c2f:
  mov eax, [esp+4]
  imul eax,9
  add eax,160
  mov ebx, 5
  cdq
  div ebx
  push eax
  fild dword ptr [esp]
  pop eax
  retn 4

c2fx:
  fild dword ptr [esp+4]
  push 9
  fimul dword ptr [esp] ; mul 9
  pop edx
  push 160
  fiadd dword ptr [esp] ; add 160
  pop edx
  push 5
  fidiv dword ptr [esp] ; div 5
  fist dword ptr [esp]
  pop eax
  retn 4


Quote from: RKC on April 29, 2019, 06:59:00 AMno reason to be such a prick about it.

José doesn't need a reason :P

RKC

Thank you! I'm actually at a tossup between this or MIPS. I'll admit it's rather nice not having to type a $ all the time hahaha! I found some good documentation on cdq but this helps a lot.

I see the problem, it's actually NASM, not sure if that makes a massive difference but the ptr will not work in it.

aw27

I attach a Visual Studio project with the asm converted to MASM.
The reason for the crash is not the CDQ, I am not using any CDQ, JJ is still learning the basics.

If you want float precision you will have to convert as I told you before. Otherwise the C will round it.

NASM is a free form assembly language.

RKC

Quote from: AW on April 29, 2019, 07:28:14 AM
I attach a Visual Studio project with the asm converted to MASM.
The reason for the crash is not the CDQ, I am not using any CDQ, JJ is still learning the basics.

If you want float precision you will have to convert as I told you before. Otherwise the C will round it.

NASM is a free form assembly language.

Thank you both, I really appreciate the time that y'all spent helping me. I've gotten past one barrier so far and onto another one in my own code. It is hard to know what C will and won't do with code sometimes, I noticed what you told me was exactly right and I appreciate it, just working on converting it now.

jj2007

Quote from: AW on April 29, 2019, 07:28:14 AMThe reason for the crash is not the CDQ, I am not using any CDQ, JJ is still learning the basics.

I know I shouldn't feed the troll, but for RKC: Without the cdq, the code will crash at the div, with exception C0000095 alias INTEGER_OVERFLOW. It may not crash if by accident edx is between 0 and 4. I've debugged the code, I know what I'm doing.

Btw, since temperatures can be negative, the correct way of dividing is using idiv:
  mov ebx, 5
  cdq
  idiv ebx

aw27

Explain how it will "crash". Do you know how DIV works?

DIV : Unsigned divide EDX:EAX by r/m32, with result stored in EAX ← Quotient, EDX ← Remainder.

What can happen is a wrong result but how will it crash? Probably you must make a proof in Basic.  :badgrin:

jj2007

When you are short of arguments, you start insulting people, José.

include \masm32\include\masm32rt.inc

.code
start:
  mov eax, 610 ; e.g. in RKC's example for C=50: 50*9+160
  mov edx, 5 ; any value except 0...4 will crash
  mov ebx, 5
  div ebx ; exception C0000095 alias INTEGER_OVERFLOW
  inkey str$(eax)
  exit
end start


You may google for "If the quotient is too large for the designated register" (with quotes).

aw27

Very good, it is the first time I have to concede to you! Time to open that bottle of champagne you have in the fridge for so long.  :t