### Author Topic: Converting from Celsius to Fahrenheit  (Read 2084 times)

#### AW

• Member
• Posts: 2583
• Let's Make ASM Great Again!
##### Re: Converting from Celsius to Fahrenheit
« Reply #15 on: April 29, 2019, 03:12:12 PM »
Actually is not yet time to open the bottle of champagne. Sorry for that.  :(
I don't believe in good luck, so I revisited the code. In the call to "num" edx is zeroed before the return. In the "C" part, all that is done after the return is push eax and call cf2. So edx is 0 (zero) within cf2 (unless you enter an absurdly high value for Celsius that makes the multiplication result over a dword). In conclusion, again, the reason for the crash is not the overflow.  :P
Sorry for this my troll friend.

#### jj2007

• Member
• Posts: 11066
• Assembler is fun ;-)
##### Re: Converting from Celsius to Fahrenheit
« Reply #16 on: April 29, 2019, 05:23:47 PM »
In the call to "num" edx is zeroed before the return. In the "C" part, all that is done after the return is push eax and call cf2. So edx is 0 (zero)

Assuming that the C compiler leaves edx intact! Actually, I had not looked at the C code, and tested the asm code in isolation - my fault. So, if the C compiler kindly does not touch edx before calling c2f, then edx is still zero, and the cdq is not needed. Still, it would be very bad to rely on that behaviour (besides, mov edx, 0 is 5 bytes, cdq is only one). Furthermore, the cdq with idiv allows negative temperatures, the mov edx, 0 doesn't.

Here is complete code for use with Pelles C and MASM:
Code: [Select]
`#include <stdio.h>#pragma comment(linker, "c2f.obj /subsystem:console" )extern int num();extern double c2f(int n);int main() {    int number = num();    // __asm int 3;    double ret = c2f(number);    printf("c2f returned %f\n", ret);    _getch();    return 0;}`
Code: [Select]
`.486                                      ; create 32 bit code.model flat, stdcall                      ; 32 bit memory modeloption casemap :none                      ; case sensitive include \Masm32\include\msvcrt.incincludelib \Masm32\lib\msvcrt.libinclude \Masm32\include\Kernel32.incincludelib \Masm32\lib\Kernel32.lib.datamessage db "The temperture in Fahrenheits: %d Reminder: %d", 10, 0request db "Enter a temperature in Celsius: ", 0celsius dd 0 ; 32-bits integer = 4 bytesformatin db "%d", 0txCrt db "msvcrt.dll", 0txPrintf db "printf", 0txScanf db "scanf", 0.codenum proc C  ;  Ask for an integer  push offset request  invoke LoadLibrary, offset txCrt  invoke GetProcAddress, eax, offset txPrintf  call dword ptr eax ; crt_printf  add esp, 4    ; remove the parameter  push offset celsius ; address of integer1, where the input is going to be stored (second parameter)  push offset formatin ; arguments are right to left (first  parameter)  invoke LoadLibrary, offset txCrt  invoke GetProcAddress, eax, offset txScanf  call dword ptr eax ; crt_printf  add esp, 8    ; remove the parameters  ; Move the value under the address integer1 to EAX  ; mov edx, 0 wrong  mov eax, celsius  retnum endpc2f proc C arg  mov eax, arg  imul eax,9  add eax,160  mov ebx, 5  ; INT 3  cdq           ; allow negative  idiv ebx      ; temperatures  push eax  fild dword ptr [esp]  pop eax  retc2f endpEND`

#### TimoVJL

• Member
• Posts: 671
##### Re: Converting from Celsius to Fahrenheit
« Reply #17 on: April 29, 2019, 06:24:54 PM »
Stupid question:
how that c2f function was defined in that exercise ?
should c2f function return int or double, or both ?

If celsius is an integer, result is also truncated to decimal, so is the fpu needed in that asm function ?

with extern int c2f(int n); C compiler can convert int to double for printf.
May the source be with you