NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: Nagaman on May 19, 2018, 07:49:11 PM
-
Hello! I'm new to assembly and I could use some help with translating my program to nasm win32.
My C code looks like this:
#include<stdio.h>
int main() {
float celsius, fahrenheit;
printf("\nSisesta temperatuur Celsiuses : ");
scanf("%f", &celsius);
fahrenheit = (1.8 * celsius) + 32;
printf("\nTemperatuur Fahrenheitides on : %f ", fahrenheit);
return (0);
}
Many thanks in advance!
-
This looks like homework too! :D
What assembly codes have you attempted so far? Are you using SSE or FPU? Show some efforts.
-
No this doesn't look like homework. Sorry.
This looks like more of "we-make-assignments" balonies trying to get some free answers on behalf of their customers. No wonder why nobody comes back for "discussions" after registering and posting a question / getting the answers. :D
-
This is NOT what is asked for. It might be some help...
Best,
Frank
;-----------------------------------------------
; converts centigrade to fahrenheit, & visa versa
;
; nasm -f bin -o myfile.com myfile.asm
;--------------------------------------
org 100h
BUFSIZ equ 8
section .data
prompt0 db 13, 10, 7, 'Pay Attention!!!', 13, 10, '$'
prompt1 db 13, 10, 'This humble program will convert', 13, 10
db 'degrees centigrade to degrees Fahrenheit,', 13, 10
db 'or Fahrenheit to centigrade (Celsius).', 13, 10
db 'Please enter "C" or "F" to indicate the', 13, 10
db 'temperature units in which you will INPUT', 13, 10
db 'the value to be converted.', 13, 10, 10 , '$'
promptc db 'Please enter degrees C to convert to F:', 13, 10, '$'
promptf db 'Please enter degrees F to convert to C:', 13, 10, '$'
that db 13, 10, "That's $"
degrees db ' degrees $'
bye db 13, 10, 10, "Thanks for playing!", 13, 10, '$'
word_10 dw 10 ; multiplier for the float-to-ascii routine
; for C->F, F->C routines
float_32 dq 32.0
float_5 dq 5.0
float_9 dq 9.0
section .bss
buffer resb BUFSIZ + 2 ; buffer for our input string
result_units resb 1 ; holds 'C' or 'F'
numbuf resb 20h ; buffer for ftoa
bcdbuf rest 1 ; 10 byte scratch area for ftoa
;--------------------
section .text
; cheap-a** cls - reset text mode
mov ax, 3
int 10h
instruct:
; tell 'em what we're gonna do, and ask for input
mov dx, prompt1
mov ah, 9
int 21h
; get input - one key, no echo
mov ah, 8
int 21h
; force uppercase
and al, 0DFh
; did they get it right?
cmp al, 'C'
je do_c2f
cmp al, 'F'
je do_f2c
; smack their a**, and make 'em do it over
mov dx, prompt0
mov ah, 9
int 21h
jmp short instruct
; store the letter we'll display at the end
; we also use it as a "flag" to decide f->c or c->f
; and set up appropriate prompt
do_c2f:
mov byte [result_units], 'F'
mov dx, promptc
jmp short both
do_f2c:
mov byte [result_units], 'C'
mov dx, promptf
both:
; display the prompt, "C" or "F", asking for input
mov ah, 9
int 21h
; get string input, set "max size" first
mov byte [buffer], BUFSIZ
mov ax, 0C0Ah
mov dx, buffer
int 21h
; since atof expects a zero-terminated string, do so.
mov bl, [buffer + 1]
xor bh, bh
mov byte [buffer + 2 + bx], 0
; convert the string to a float in st(0)
; remember that input text starts at 2 bytes into the buffer
mov si, buffer + 2
call atof
jnc good_num
; if they gave us trash, give 'em trash back
; and make 'em do it over
mov dx, prompt0
int 21h
mov dx, promptc
cmp byte [result_units], 'F'
je both
mov dx, promptf
jmp short both
good_num:
; okay, they did right, do the calculation they want
cmp byte [result_units], 'C'
jne calc_c2f
fsub qword [float_32]
fmul qword [float_5]
fdiv qword [float_9]
jmp short display
calc_c2f:
fmul qword [float_9]
fdiv qword [float_5]
fadd qword [float_32]
; Whew! That was tough!
display:
; convert st(0) to ascii string at di - cx decimal places
mov cx, 2
mov di, numbuf
call ftoa
; ftoa returns a zero-terminated string,
; fix it for int 21h/9 - '$'-terminate
dec di
reterminate:
cmp byte [di + 1], 1
inc di
jnc reterminate
mov byte [di], '$'
; tell 'em what we're going to do
mov ah, 9
mov dx, that
int 21h
; tell 'em the number
mov dx, numbuf
int 21h
; and the units
mov dx, degrees
int 21h
mov ah, 2
mov dl, [result_units]
int 21h
; say Buhbye - enhancement - go again?
mov ah, 9
mov dx, bye
int 21h
exit:
mov ah,4Ch
int 21h
;------------------------------------------------
; atof - converts ascii string to float
; expects: si pointed to zero-terminated string
; returns: float in st(0)
; carry set if invalid digit encountered
;-------------------------------------------------
atof:
push ax
push bx
push cx
push dx
push di
push si
xor bx, bx
xor cx, cx
dec cx ; set cx FFFF - no point found
xor dx, dx
mov byte [bcdbuf + 9], 0 ; assume positive
mov di, si ; save our "beginning of buffer"
.af0:
mov al, [si]
inc si
cmp al, '-'
jnz .notneg
mov byte [bcdbuf + 9], 80h
jmp short .af0
.notneg:
cmp al, '.'
jnz .notpt
inc cx
jmp short .af0
.notpt:
cmp al, ' '
jz .af0
cmp cx, 0FFFFh
jz .af05
inc cx
.af05
or al, al ; end of string?
jnz .af0
dec si
dec si
cmp cx, 0FFFFh
jnz .af07
xor cx, cx
jmp short .af1
.af07
dec cx
.af1:
cmp si, di
jc .done
mov al, [si]
dec si
cmp al, ' '
jz .af1
cmp al, '-'
jz .af1
cmp al, '.'
jz .af1
cmp al, 3Ah
jnc .invalid
cmp al, 30h
jc .invalid
and al, 0Fh
or dh, dh
jnz .notfirst
or dl, al
inc dh
jmp short .af1
.notfirst:
shl al, 4
or dl, al
mov [bcdbuf + bx], dl
xor dx, dx
inc bx
jmp .af1
.invalid
stc
jmp short .done3
.done
or dh, dh
jz .padbcd
and dl, 0Fh
mov [bcdbuf + bx], dl
inc bx
.padbcd
cmp bx, byte 9
jz .done2
mov byte [bcdbuf + bx], 0
inc bx
jmp short .padbcd
.done2
fbld [bcdbuf]
or cx, cx
jz .done25
.tendiv:
fidiv word [word_10]
loop .tendiv
.done25
clc
.done3:
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret
;--------------------------------------------
;-----------------------------------------------------
; ftoa - converts floating point to string
;
; Based on some code "sponged" from a post to clax
; From: "Jim Morrison" <astrolabe at ntplx dot net>
;
; Expects: Number to convert is on stack top - st(0)
; di points to buffer to store string
; cx = Decimal Places.
;-------------------------------------------------------------
ftoa:
push ax
push cx
push dx
push di
push si
mov dx, cx ; save a copy of dec places
; if no decimal (integer)
jcxz .f2a2 ; skip multiply by ten loop
.f2a1: ; else loop to "scale" number
fimul word [word_10]
loop .f2a1
.f2a2:
fbstp [bcdbuf] ; convert to bcd and store
mov si, bcdbuf ; we'll pull digits from there
mov cx, 9
.f2a3:
lodsb ; get a pair of digits
mov ah, al ; move a copy to ah
shr ah, 4 ; shift out low nibble, keeping high
and ax, 0F0Fh ; mask out the digits we want
add ax, 3030h ; convert 'em both to ascii
push ax
mov al, ah ; swap and store the other digit
push ax
loop .f2a3 ; until done
cmp byte [bcdbuf+9], 0 ; sign flag at bcdbuf + 9 ?
je .f2a6
mov al, '-' ; minus sign if we need it
stosb ; store it at front of our string
.f2a6:
mov cx, 18
xor dh, dh
inc dl
.poploop
pop ax
cmp al, '0'
jnz .store
or dh, dh
jnz .store
jmp short .nostore
.store
stosb
inc dh
.nostore
cmp cl, dl
jne .nopoint
or dh, dh ; if we haven't encountered a non-zero
jnz .nolz
mov al, '0' ; put a zero before the decimal point
stosb
.nolz
mov al, '.' ; decimal point
stosb ; and store it
inc dh
.nopoint
loop .poploop
mov al, 0
stosb
pop si
pop di
pop dx
pop cx
pop ax
ret
;--------------------------------------------------
-
This is NOT what is asked for. It might be some help...
Best,
Frank
;-----------------------------------------------
; converts centigrade to fahrenheit, & visa versa
;
; nasm -f bin -o myfile.com myfile.asm
;--------------------------------------
org 100h
BUFSIZ equ 8
section .data
prompt0 db 13, 10, 7, 'Pay Attention!!!', 13, 10, '$'
prompt1 db 13, 10, 'This humble program will convert', 13, 10
db 'degrees centigrade to degrees Fahrenheit,', 13, 10
db 'or Fahrenheit to centigrade (Celsius).', 13, 10
db 'Please enter "C" or "F" to indicate the', 13, 10
db 'temperature units in which you will INPUT', 13, 10
db 'the value to be converted.', 13, 10, 10 , '$'
promptc db 'Please enter degrees C to convert to F:', 13, 10, '$'
promptf db 'Please enter degrees F to convert to C:', 13, 10, '$'
that db 13, 10, "That's $"
degrees db ' degrees $'
bye db 13, 10, 10, "Thanks for playing!", 13, 10, '$'
word_10 dw 10 ; multiplier for the float-to-ascii routine
; for C->F, F->C routines
float_32 dq 32.0
float_5 dq 5.0
float_9 dq 9.0
section .bss
buffer resb BUFSIZ + 2 ; buffer for our input string
result_units resb 1 ; holds 'C' or 'F'
numbuf resb 20h ; buffer for ftoa
bcdbuf rest 1 ; 10 byte scratch area for ftoa
;--------------------
section .text
; cheap-a** cls - reset text mode
mov ax, 3
int 10h
instruct:
; tell 'em what we're gonna do, and ask for input
mov dx, prompt1
mov ah, 9
int 21h
; get input - one key, no echo
mov ah, 8
int 21h
; force uppercase
and al, 0DFh
; did they get it right?
cmp al, 'C'
je do_c2f
cmp al, 'F'
je do_f2c
; smack their a**, and make 'em do it over
mov dx, prompt0
mov ah, 9
int 21h
jmp short instruct
; store the letter we'll display at the end
; we also use it as a "flag" to decide f->c or c->f
; and set up appropriate prompt
do_c2f:
mov byte [result_units], 'F'
mov dx, promptc
jmp short both
do_f2c:
mov byte [result_units], 'C'
mov dx, promptf
both:
; display the prompt, "C" or "F", asking for input
mov ah, 9
int 21h
; get string input, set "max size" first
mov byte [buffer], BUFSIZ
mov ax, 0C0Ah
mov dx, buffer
int 21h
; since atof expects a zero-terminated string, do so.
mov bl, [buffer + 1]
xor bh, bh
mov byte [buffer + 2 + bx], 0
; convert the string to a float in st(0)
; remember that input text starts at 2 bytes into the buffer
mov si, buffer + 2
call atof
jnc good_num
; if they gave us trash, give 'em trash back
; and make 'em do it over
mov dx, prompt0
int 21h
mov dx, promptc
cmp byte [result_units], 'F'
je both
mov dx, promptf
jmp short both
good_num:
; okay, they did right, do the calculation they want
cmp byte [result_units], 'C'
jne calc_c2f
fsub qword [float_32]
fmul qword [float_5]
fdiv qword [float_9]
jmp short display
calc_c2f:
fmul qword [float_9]
fdiv qword [float_5]
fadd qword [float_32]
; Whew! That was tough!
display:
; convert st(0) to ascii string at di - cx decimal places
mov cx, 2
mov di, numbuf
call ftoa
; ftoa returns a zero-terminated string,
; fix it for int 21h/9 - '$'-terminate
dec di
reterminate:
cmp byte [di + 1], 1
inc di
jnc reterminate
mov byte [di], '$'
; tell 'em what we're going to do
mov ah, 9
mov dx, that
int 21h
; tell 'em the number
mov dx, numbuf
int 21h
; and the units
mov dx, degrees
int 21h
mov ah, 2
mov dl, [result_units]
int 21h
; say Buhbye - enhancement - go again?
mov ah, 9
mov dx, bye
int 21h
exit:
mov ah,4Ch
int 21h
;------------------------------------------------
; atof - converts ascii string to float
; expects: si pointed to zero-terminated string
; returns: float in st(0)
; carry set if invalid digit encountered
;-------------------------------------------------
atof:
push ax
push bx
push cx
push dx
push di
push si
xor bx, bx
xor cx, cx
dec cx ; set cx FFFF - no point found
xor dx, dx
mov byte [bcdbuf + 9], 0 ; assume positive
mov di, si ; save our "beginning of buffer"
.af0:
mov al, [si]
inc si
cmp al, '-'
jnz .notneg
mov byte [bcdbuf + 9], 80h
jmp short .af0
.notneg:
cmp al, '.'
jnz .notpt
inc cx
jmp short .af0
.notpt:
cmp al, ' '
jz .af0
cmp cx, 0FFFFh
jz .af05
inc cx
.af05
or al, al ; end of string?
jnz .af0
dec si
dec si
cmp cx, 0FFFFh
jnz .af07
xor cx, cx
jmp short .af1
.af07
dec cx
.af1:
cmp si, di
jc .done
mov al, [si]
dec si
cmp al, ' '
jz .af1
cmp al, '-'
jz .af1
cmp al, '.'
jz .af1
cmp al, 3Ah
jnc .invalid
cmp al, 30h
jc .invalid
and al, 0Fh
or dh, dh
jnz .notfirst
or dl, al
inc dh
jmp short .af1
.notfirst:
shl al, 4
or dl, al
mov [bcdbuf + bx], dl
xor dx, dx
inc bx
jmp .af1
.invalid
stc
jmp short .done3
.done
or dh, dh
jz .padbcd
and dl, 0Fh
mov [bcdbuf + bx], dl
inc bx
.padbcd
cmp bx, byte 9
jz .done2
mov byte [bcdbuf + bx], 0
inc bx
jmp short .padbcd
.done2
fbld [bcdbuf]
or cx, cx
jz .done25
.tendiv:
fidiv word [word_10]
loop .tendiv
.done25
clc
.done3:
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret
;--------------------------------------------
;-----------------------------------------------------
; ftoa - converts floating point to string
;
; Based on some code "sponged" from a post to clax
; From: "Jim Morrison" <astrolabe at ntplx dot net>
;
; Expects: Number to convert is on stack top - st(0)
; di points to buffer to store string
; cx = Decimal Places.
;-------------------------------------------------------------
ftoa:
push ax
push cx
push dx
push di
push si
mov dx, cx ; save a copy of dec places
; if no decimal (integer)
jcxz .f2a2 ; skip multiply by ten loop
.f2a1: ; else loop to "scale" number
fimul word [word_10]
loop .f2a1
.f2a2:
fbstp [bcdbuf] ; convert to bcd and store
mov si, bcdbuf ; we'll pull digits from there
mov cx, 9
.f2a3:
lodsb ; get a pair of digits
mov ah, al ; move a copy to ah
shr ah, 4 ; shift out low nibble, keeping high
and ax, 0F0Fh ; mask out the digits we want
add ax, 3030h ; convert 'em both to ascii
push ax
mov al, ah ; swap and store the other digit
push ax
loop .f2a3 ; until done
cmp byte [bcdbuf+9], 0 ; sign flag at bcdbuf + 9 ?
je .f2a6
mov al, '-' ; minus sign if we need it
stosb ; store it at front of our string
.f2a6:
mov cx, 18
xor dh, dh
inc dl
.poploop
pop ax
cmp al, '0'
jnz .store
or dh, dh
jnz .store
jmp short .nostore
.store
stosb
inc dh
.nostore
cmp cl, dl
jne .nopoint
or dh, dh ; if we haven't encountered a non-zero
jnz .nolz
mov al, '0' ; put a zero before the decimal point
stosb
.nolz
mov al, '.' ; decimal point
stosb ; and store it
inc dh
.nopoint
loop .poploop
mov al, 0
stosb
pop si
pop di
pop dx
pop cx
pop ax
ret
;--------------------------------------------------
HAHAHA :D
-
Hello! I'm new to assembly and I could use some help with translating my program to nasm win32.
To 32-bit or 64-bit? Windows or Linux?
Below is one translation of that C code, for x64 running Windows and in Nasm syntax. It was done by getting a C compiler to output assembly then tweaking the results for posting.
Assemble with 'nasm -fwin64 program.asm'. You will have to figure out how to link the result (it needs the C runtime, eg. msvcrt.dll on Windows).
segment .text
extern printf
extern scanf
global main
main:
push rbp
mov rbp, rsp
sub rsp, 16
sub rsp, 32
mov rcx, .k1
call printf
lea rax, [rbp-8]
push rax
mov rcx, .k2
pop rdx
call scanf
add rsp, 32
cvtss2sd xmm0, [rbp-8]
mulsd xmm0, [.r1]
addsd xmm0, [.r2]
cvtsd2ss xmm0, xmm0
movd [rbp-16], xmm0
sub rsp, 32
mov rcx, .k3
movd xmm1, [rbp-16]
cvtss2sd xmm1, xmm1
movq rdx, xmm1
call printf
add rsp, 32
mov eax, 0
add rsp, 16
pop rbp
ret
segment .data
align 8
.k1:
db 10,"Sisesta temperatuur Celsiuses : ",0
.k2:
db "%f",0
.k3:
db 10,"Temperatuur Fahrenheitides on : %f ",0
align 8
.r1:
dq 4610785298501913805 ; 1.8
.r2:
dq 4629700416936869888 ; 32
-
Hello! I'm new to assembly and I could use some help with translating my program to nasm win32.
To 32-bit or 64-bit? Windows or Linux?
As the OP asked for Win32, it is logical to assune he means 32-bit Windows (after all, that is what Win32 means!)
-
Hello! I'm new to assembly and I could use some help with translating my program to nasm win32.
To 32-bit or 64-bit? Windows or Linux?
As the OP asked for Win32, it is logical to assune he means 32-bit Windows (after all, that is what Win32 means!)
Well, the Windows API is called Win32 for both 32- and 64-bit Windows. (It will uses libraries such as "gdi32.dll" on both.)
So it's not clear whether the "win32" refers to that, or to Nasm's '-fwin32' option for 32-bit code.
(Edit: just to add to the confusion, I said it should be assembled with -fwin32! It should be -fwin64. Now updated.)
Anyway, my code sample is for 64-bit code using Win64 call convention. If the OP uses the same method to generate the assembly code, then they can choose. eg:
gcc -O0 -S -masm=intel -fverbose-asm program.c
creates program.s (not nasm syntax).