Почему мой код приводит к ошибке сегментации, но не с другим начальным параметром? - PullRequest
1 голос
/ 17 февраля 2020

Я перевожу C программу на ассемблер. У меня есть особая проблема с переводом одной из вспомогательных функций. Функция работает в C. Когда я пытаюсь протестировать его в ассемблере, я получаю ошибку сегментации, если stack_size равен 0 в начале, но когда он равен 1, ошибка сегментации больше не появляется.

C функция:

void addToStack(long *stack, int *stacksize, int number) {
(*stacksize)++;    
stack[*stacksize-1] = number;
}

Обратите внимание, что стек - это массив long. Размер стека - это на самом деле не размер массива, а количество элементов, установленных внутри. Например, новый массив должен иметь stack_size = 0, и если мы поместим число в массив, мы должны поместить в позицию stack_size и затем увеличить stack_size.

Это реализация кода в NASM с использованием синтаксиса AT & T:

//addToStack function
.globl addToStack
addToStack:
//Stack pointer is %rdi
//Stack size pointer is %rsi
//Number (to add) is %rdx

//Get stack size
movq (%rsi), %r8
//Get size of stack in bytes
imul $8, %r8
//Add size of stack to stack pointer (to move it)
add %r8, %rdi
//Put number in memory at rdi
movq %rdx, (%rdi)
//Get stack size
movq (%rsi), %r9
//Increment stack size
add $1, %r9
//Put new size in size pointer memory
movq %r9, (%rsi)

ret

Это тест:

//Tests addToStack function
void testAddToStack(TestObjs *obj) {
int stack_size = 0;
long myStack[5];
memset(myStack, 0, 5*sizeof(long));

addToStack(myStack, &stack_size, 1);
ASSERT(stack_size == 1);
ASSERT(myStack[1] == 1); 

addToStack(myStack, &stack_size, 2);

addToStack(myStack, &stack_size, 3);
addToStack(myStack, &stack_size, 4);
addToStack(myStack, &stack_size, 5);
ASSERT(stack_size == 5);
ASSERT(myStack[1] == 2); 
ASSERT(myStack[2] == 3);
ASSERT(myStack[3] == 4);
ASSERT(myStack[4] == 5);   
}

Если вы измените stack_size в функции теста на 1 вместо 0, то ошибки сегментации не будет. Почему? Что я делаю неправильно?

...