Другие языки программирования и технологии

Простая задача на FASM (ассемблер) помогите 3 дня мучаюсь!!!

Напиши на FASM код для задачи: Найти длину окружности L и площадь круга S заданного радиуса R:
L=2·π·R, S=π·R^2. В качестве значения π использовать 3.14

Код программы:

format PE console
entry start

include 'C:\Program Files (x86)\FASM\INCLUDE\win32a.inc'

section '.data' data readable writeable
pi dd 3.14 ; значение числа пи
R dd ? ; радиус круга
L dd ? ; длина окружности
S dd ? ; площадь круга

section '.text' code readable executable
main:
; запрашиваем радиус у пользователя
invoke StdOut, prompt
invoke StdIn, R
; вычисляем длину окружности
fldpi
fmul dword [R]
fmul qword 2.0
fstp dword [L]
; вычисляем площадь круга
fld dword [R]
fmul dword [R]
fldpi
fmul
fstp dword [S]
; выводим результаты на экран
invoke StdOut, resultL, dword [L]
invoke StdOut, resultS, dword [S]
; выходим из программы
invoke ExitProcess, 0

prompt db 'Введите радиус круга: ', 0
resultL db 'Длина окружности равна: ', 0
resultS db 'Площадь круга равна: ', 0

Пишет что проблема в (fmul dword 2.0)
Как в точности выглядит сообщение? В тексте я вижу qword 2.0, а не dword.
Можно не умножать на 2, а сложить пи*радиус сам с собой. Ещё можно вынести 2 в секцию data.
Канатбек Байдембеков
Канатбек Байдембеков
48 068
Лучший ответ
конкретно - какую ошибку выводит?
Прежде чем перейти к решению задачи на языке FASM, необходимо описать саму задачу для полного понимания проблемы.

Задача: необходимо написать программу на ассемблере FASM, которая будет получать две целочисленные переменные из пользовательского ввода и выводить их сумму на экран.

Решение: для начала, необходимо создать файл программы с расширением .asm и открыть его в редакторе кода (например, Notepad++).

Затем нужно объявить секцию .data для переменных и секцию .code для кода программы. В этой секции необходимо написать следующие команды:
 ```  

section .data

msg1 db 'Введите первое число: ',0

msg2 db 'Введите второе число: ',0

sum_msg db 'Сумма: ',0

num1 dd 0

num2 dd 0

sum dd 0



section .code

global _start



_start:

; выводим сообщение "Введите первое число:"

mov eax, 4

mov ebx, 1

mov ecx, msg1

mov edx, 21

int 0x80



; считываем первое число в переменную num1

mov eax, 3

mov ebx, 2

mov ecx, num1

mov edx, 4

int 0x80



; выводим сообщение "Введите второе число:"

mov eax, 4

mov ebx, 1

mov ecx, msg2

mov edx, 21

int 0x80



; считываем второе число в переменную num2

mov eax, 3

mov ebx, 2

mov ecx, num2

mov edx, 4

int 0x80



; складываем числа и сохраняем результат в переменную sum

mov eax, [num1]

add eax, [num2]

mov [sum], eax



; выводим сообщение "Сумма:"

mov eax, 4

mov ebx, 1

mov ecx, sum_msg

mov edx, 7

int 0x80



; выводим результат сложения (переменную sum)

mov eax, 4

mov ebx, 1

mov ecx, [sum]

mov edx, 4

int 0x80



; завершаем программу

mov eax, 1

xor ebx, ebx

int 0x80

```


Разберем подробнее каждую команду:

1) Секция .data объявляет переменные, которые будут использоваться в программе:
msg1, msg2 и sum_msg - это строки вывода на экран;
num1, num2 и sum - целочисленные переменные.

2) Секция .code содержит код программы, начиная со специального метки _start, которая обозначает начало программы.

3) Команда mov используется для перемещения или копирования данных. Например, команда mov eax, 4 перемещает число 4 в регистр eax.

4) Команда int используется для вызова прерывания операционной системы. Например, вызов прерывания 0x80 (в командах mov eax, 4 и mov eax, 3) означает вызов системной функции.

5) Команда add используется для сложения двух чисел.

6) Команда xor используется для очистки регистра.

7) Команда завершения программы - int 0x80 с параметром 1 (mov eax, 1).

Таким образом, программа на FASM для решения данной задачи будет выглядеть примерно так. Конечно, это только один из возможных вариантов решения, и в зависимости от задачи могут потребоваться дополнительные команды и алгоритмы.
Николай Кудик
Николай Кудик
4 495
Ошибка возникает из-за того, что в команде fmul dword 2.0 вы пытаетесь умножить на вещественное число 2.0, но операнд fmul принимает только целочисленные значения. Для умножения на вещественное число нужно использовать команду fld для загрузки значения на вершину стека сопроцессора, а затем команду fmul для умножения на вершине стека.

Исправленный код программы может выглядеть так:
 format PE console  

entry start
include 'C:\Program Files (x86)\FASM\INCLUDE\win32a.inc'
section '.data' data readable writeable
pi dd 3.14 ; значение числа пи
R dd ? ; радиус круга
L dd ? ; длина окружности
S dd ? ; площадь круга
section '.text' code readable executable
start:
; запрашиваем радиус у пользователя
invoke StdOut, prompt
invoke StdIn, R
; вычисляем длину окружности
fldpi
fld dword [R]
fmul
fmul dword 2
fstp dword [L]
; вычисляем площадь круга
fld dword [R]
fmul
fldpi
fmul
fstp dword [S]
; выводим результаты на экран
invoke StdOut, resultL, dword [L]
invoke StdOut, resultS, dword [S]
; выходим из программы
invoke ExitProcess, 0
prompt db 'Введите радиус круга: ', 0
resultL db 'Длина окружности равна: ', 0
resultS db 'Площадь круга равна: ', 0

В этом коде мы используем команду fld для загрузки значения числа пи и радиуса на вершину стека, а затем команду fmul для умножения значений на вершине стека. Также мы используем команду fmul dword 2 для умножения на целочисленную константу 2.
Eugen Reim
Eugen Reim
3 520
Eugen Reim Ошибка возникает из-за того, что в команде fadd отсутствует операнд. Команда fadd должна иметь один операнд, который может быть регистром FPU, памятью или константой.

Возможно, в вашем коде отсутствует команда, которая загружает значение из памяти или регистра FPU на вершину стека FPU перед использованием команды fadd.

Если в вашем коде уже есть команда для загрузки значения на стек FPU, убедитесь, что она правильно загружает значение, и что стек FPU находится в правильном состоянии.
 format PE console 
entry start

include 'C:\Program Files (x86)\FASM\INCLUDE\win32a.inc'

section '.data' data readable writeable
pi dd 3.14 ; значение числа пи
R dd ? ; радиус круга
L dd ? ; длина окружности
S dd ? ; площадь круга

section '.text' code readable executable
start:
; запрашиваем радиус у пользователя
invoke StdOut, prompt
invoke StdIn, R
; вычисляем длину окружности
fldpi
fmul dword [R]
fld1
fadd
fmul
fstp dword [L]
; вычисляем площадь круга
fld dword [R]
fmul dword [R]
fldpi
fmul
fstp dword [S]
; выводим результаты на экран
invoke StdOut, resultL, dword [L]
invoke StdOut, resultS, dword [S]
; выходим из программы
invoke ExitProcess, 0

prompt db 'Введите радиус круга: ', 0
resultL db 'Длина окружности равна: ', 0
resultS db 'Площадь круга равна: ', 0
** Альфред **
1 369
В FASM fmulинструкция умножает два верхних значения с плавающей запятой в стеке FPU и сохраняет результат на вершине стека. Однако 2.0не является допустимым операндом FPU.

Чтобы решить эту проблему, вы можете использовать fld1инструкцию для загрузки значения 1.0в стек FPU, а затем использовать fadd, чтобы добавить его к себе, фактически удвоив значение до 2.0.

Вот исправленный код:

 format PE console 
entry start

include 'C:\Program Files (x86)\FASM\INCLUDE\win32a.inc'

section '.data' data readable writeable
pi dd 3.14 ; value of pi
R dd ? ; radius of the circle
L dd ? ; circumference
S dd ? ; the area of the circle

section '.text' code readable executable
start:
; requesting the radius from the user
invoke StdOut, prompt
invoke StdIn, R
; calculating the circumference
fldpi
fmul dword [R]
fld1
fadd st0, st0
fmul
fstp dword [L]
; calculate the area of the circle
fld dword [R]
fmul dword [R]
fldpi
fmul
fstp dword [S]
; output the results to the screen
invoke StdOut, resultL, dword [L]
invoke StdOut, resultS, dword [S]
; exit the program
invoke ExitProcess, 0

prompt db 'Enter the radius of the circle: ', 0
resultL db 'The circumference is: ', 0
resultS db 'The area of the circle is: ', 0