Математический сопроцессор x87 FPU
Аннотация
Целью четвертой лабораторной работы является получение навыков работы с математическим сопроцессором.
Ход работы
- Перейдите в каталог для файлов лабораторных работ по курсу "Архитектура современных ЭВМ".
- Создайте каталог для файлов данной лабораторной работы.
- Подготовьте файл с кодом программы:
/** * math.S -- вычисляет и печатает число Пи * * Copyright (c) 2014 Petrozavodsk State University * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. */ /* Объявляем внешние имена (необязательно) */ .extern printf .extern scanf /* Секция данных */ .data fmt: .asciz "%.25lf\n" # форматная строка для printf dbl: .double .0 # вещественнозначное число типа double /* Секция команд процессора */ .text .global main # имя точки входа для компоновщика /** * main * главная функция языка Си - точка входа в программу */ main: pushl %ebp # сохраняем контекст стека movl %esp, %ebp pushl $dbl # передаем адрес для размещения результата call calc_pi_1 # вызываем функцию расчета числа Пи # с помощью инструкции fldpi addl $4, %esp # восстанавливаем указатель стека pushl $dbl # передаем адрес числа Пи call print_double_by_ptr # вызываем функцию вывода числа на экран addl $4, %esp # восстанавливаем указатель стека pushl $dbl # передаем адрес для размещения результата call calc_pi_2 # вызываем функцию расчета числа Пи # с помощью формулы Мэчина addl $4, %esp # восстанавливаем указатель стека pushl $dbl # передаем адрес числа Пи call print_double_by_ptr # вызываем функцию вывода числа на экран addl $4, %esp # восстанавливаем указатель стека movl %ebp, %esp # восстанавливаем контекст стека popl %ebp ret # завершаем выполнение программы /** print_double_by_ptr * выводит вещественнозначное число типа double на экран с помощью вызова * функции printf стандартной библиотеки языка Си */ print_double_by_ptr: pushl %ebp # сохраняем контекст стека movl %esp, %ebp movl 8(%ebp), %eax # получаем указатель на число pushl 4(%eax) # сохраняем старшую половину pushl (%eax) # сохраняем младшую половину pushl $fmt # сохраняем адрес форматной строки call printf # выводим на экран addl $12, %esp # восстанавливаем указатель стека movl %ebp, %esp # восстанавливаем контекст стека popl %ebp ret # завершаем подпрограмму /** calc_pi_1 * вычисляет значение числа пи с помощью встроенной функции загрузки * числа пи на вершину стека fpu */ calc_pi_1: pushl %ebp # сохраняем контекст стека movl %esp, %ebp fldpi # загружаем число Пи на вершину стека movl 8(%ebp), %eax # извлекаем из параметра адрес fstpl (%eax) # выталкиваем результат по адресу movl %ebp, %esp # восстанавливаем контекст стека popl %ebp ret # завершаем подпрограмму /** calc_pi_2 * вычисляет значение числа пи с помощью формулы Мэчина */ calc_pi_2: pushl %ebp # сохраняем контекст стека movl %esp, %ebp subl $4, %esp # резервируем память под локальную переменную fld1 # st(0) <- 1 movl $239, -4(%ebp) fild -4(%ebp) # st(0) <- 239, st(1) <- 1 fpatan # st(0) <- arctg(1/239) fld1 # st(0) <- 1, st(0) <- arctg(1/239) movl $5, -4(%ebp) fild -4(%ebp) # st(0) <- 5, st(1) <- 1, st(2) <- arctg(1/239) fpatan # st(0) <- arctg(1/5), st(1) <- arctg(1/239) movl $4, -4(%ebp) fild -4(%ebp) # st(0) <- 4, st(1) <- arctg(1/5), st(2) <- arctg(1/239) fmulp # st(0) <- 4 * arctg(1/5), st(1) <- arctg(1/239) fsubp # st(0) <- 4 * arctg(1/5) - arctg(1/239) fild -4(%ebp) # st(0) <- 4, st(1) <- 4 * arctg(1/5) - arctg(1/239) fmulp # st(0) <- 4 * (4 * arctg(1/5) - arctg(1/239)) movl 8(%ebp), %eax # извлекаем из параметра адрес fstpl (%eax) # выталкиваем результат по адресу movl %ebp, %esp # восстанавливаем контекст стека popl %ebp ret # завершаем подпрограмму
- Изучите способ организации подпрограмм в коде на языке ассемблера, передачи значения в подпрограмму.
- Изучите механизм организации вычислений и размещения операндов выражений на стеке FPU на примере вычисления числа Пи с помощью инструкции FPU (calc_pi_1) и по формуле Мэчина (calc_pi_2):
- Реализуйте функцию вычисления числа Пи по формуле Штёрмера:
- Перепишите функцию main на языке C.