Здравствуйте.
Сейчас в универе идет курс системного программного обеспечения, т.е. сплошное программирование на асме. В распоряжении только Linux. Первую лабораторную сделал без проблем, т.к. стоял GNU/Linux Debian i386. Потом дошли руки - сменил систему на GNU/Linux Debian amd64, и сразу возникли проблемы.
Для второй лабораторной требуется модуль из первой лабораторной, следовательно начал переводить код на 64-разрядную архитектуру.
Для начала представлю код, который был:
Показать
#include <iostream>
#include <ctime>
#include <stdlib.h>
using namespace std;
int *processing(int*, int);
int main()
{
srand(time(NULL));
int a[30];
for(int i = 0; i < 30; i++)
{
a[i] = rand()%10;
}
for(int i = 0; i < 30; i++)
{
cout << a[i] << " ";
}
cout << endl;
int *result;
result = processing(a, 30);
cout << "Минимальное значение в массиве: " << result[0] << endl;
cout << "Положение минимального значения: " << result[1] << endl;
cout << "Количество нулей до минимального значения: " << result[2] << endl;
cout << "Среднее положение после минимального: " << result[3] << endl;
return 0;
}
processing.cpp:
void *processing(int *array, int length)
{
int min = array[0];
int min_pos = 0;
for(int i = 0; i < length; i++)
{
if(min >= array[i])
{
min = array[i];
min_pos = i;
}
}
int zero_count = 0;
for(int i = 0; i < min_pos; i++)
{
if(array[i] == 0)
{
zero_count++;
}
}
min_pos++;
int middle = length - min_pos;
middle >>= 1;
middle += min_pos;
middle++;
if(middle == 31)
{
middle = -1;
}
int *result = new int[4];
result[0] = min;
result[1] = min_pos;
result[2] = zero_count;
result[3] = middle;
return result;
}
main.s:
.data
print_format:
.string "\n"
print_format_array:
.string "%d "
print_format_result:
.string "%s%d\n"
print_min:
.string "Минимальное значение в массиве: "
print_min_pos:
.string "Положение минимального значения: "
print_zero_count:
.string "Количество нулей до минимального значения: "
print_middle:
.string "Среднее положение после минимального: "
array:
.long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
array_end:
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
pushl $0
call time
pushl %eax
call srand
movl $array, %ebx
generate_loop:
call rand
xorl %edx, %edx
movl $10, %ecx
divl %ecx
movl %edx, (%ebx)
addl $4, %ebx
cmpl $array_end, %ebx
jne generate_loop
movl $array, %eax
print_loop:
pusha
pushl (%eax)
pushl $print_format_array
call printf
addl $8, %esp
popa
addl $4, %eax
cmpl $array_end, %eax
jne print_loop
pusha
pushl $print_format
call printf
addl $4, %esp
popa
pushl $30
pushl $array
call _Z10processingPii
pusha
movl (%eax), %ebx
pushl %ebx
pushl $print_min
pushl $print_format_result
call printf
addl $12, %esp
popa
addl $4, %eax
pusha
movl (%eax), %ebx
pushl %ebx
pushl $print_min_pos
pushl $print_format_result
call printf
addl $12, %esp
popa
addl $4, %eax
pusha
movl (%eax), %ebx
pushl %ebx
pushl $print_zero_count
pushl $print_format_result
call printf
addl $12, %esp
popa
addl $4, %eax
pusha
movl (%eax), %ebx
pushl %ebx
pushl $print_middle
pushl $print_format_result
call printf
addl $12, %esp
popa
movl %ebp, %esp
popl %ebp
ret
processing.s случайно удалил при следующих действиях.
Для того, чтобы разобраться с переводом кода, скомпилировал исходники на C++ в g++ с флагом -S. В полученном коде вроде как разобрался, но остались некоторые вопросы:
1) gcc ругается на инструкции pusha и popa. Чем их можно заменить?
2) С вызовом time и srand разобрался, т.к. передается один параметр и он заносится в регистр %rdi, а не кладется в стек. А как быть с printf (т.е. надо передать больше одного параметра)? Способ, который применял на 32-разрядной архитектуре (т.е. положить параметры в стек в обратном порядке) компилятору не нравится.
3) Команды имеют постфикс q. В случае 32-разрядной архитектуры для объявления массива я использовал .long, а в командах постфикс l, а как сейчас объявить массив чисел, чтобы был полностью занят весь регистр, а не его половина?
Также есть пара вопросов по второй лабораторной (методички написаны для MS-DOS, поэтому они не рулят, благо препод разрешает делать под любую систему):
1) В консоли надо сделать три окна (ввод начальных данных, вывод результата, меню). Если я правильно понял то, что мне сказал google, то надо использовать FrameBuffer. Но вот как его правильно использовать? С эти никак разобраться не могу. Может быть есть другие способы?
2) Надо организовать поддержку мыши. Информацию на эту тему я так и не смог найти :( Можете что-нибудь подсказать?
Заранее спасибо.
P.S. Забыл указать, что окна должны быть разноцветные и реализованы с помощью прямой записи в видеопамять.