Кадр стека MIPS (и путаница с инструкциями "addiu") - PullRequest
1 голос
/ 26 июля 2011

Я новичок в MIPS и пытаюсь понять разбор функции.
(РЕДАКТИРОВАТЬ: она динамически связана с /lib/ld-uClib.so.0 и использует некоторые обычные функции libc, поэтому япредположим, что он был написан на C с использованием цепочки инструментов uClibc, и поэтому должен иметь эту вызывающую процедуру, стековый фрейм и т. д.)в конце функции он выполняет:

  4009e0:   8fbc0018    lw  gp,24(sp)
  4009e4:   34088670    li  t0,0x8670
  4009e8:   03a8e821    addu    sp,sp,t0    ; sp+=0x8670; //remove local space
  4009ec:   8fbf7fdc    lw  ra,32732(sp)
  4009f0:   8fbe7fd8    lw  s8,32728(sp)
  4009f4:   8fb77fd4    lw  s7,32724(sp)
  4009f8:   8fb67fd0    lw  s6,32720(sp)
  4009fc:   8fb57fcc    lw  s5,32716(sp)
  400a00:   8fb47fc8    lw  s4,32712(sp)
  400a04:   8fb37fc4    lw  s3,32708(sp)
  400a08:   8fb27fc0    lw  s2,32704(sp)
  400a0c:   8fb17fbc    lw  s1,32700(sp)
  400a10:   8fb07fb8    lw  s0,32696(sp)
  400a14:   03e00008    jr  ra
  400a18:   27bd7fe0    addiu   sp,sp,32736 ; sp += 0x7fe0

Вопрос № 1:
Несмотря на то, что я некоторое время искал в Интернете, я до сих пор не совсем понимаю, как предполагается использовать gp вStackFrame.

В частности, в документах, которые я прочитал, говорится, что стандарт процедуры вызова a0-a3 используется для ввода функции, v0-v3 для вывода функции, s0-s8 сохраняются между вызовами, а t0-t9 не сохраняютсячерез любой звонок.Таким образом, нажатие и выталкивание s0-s8 имеет смысл. Но почему в мире он устанавливает gp в соответствии со значением в t9!?

Вопрос № 2:
Я не понимаю, почему он перемещает указатель стека дважды.Кажется, он резервирует локальное пространство дважды.

И, кроме того, инструкция addiu разбирается с отрицательным числом, которое не имеет смысла, так как 'u' означает беззнаковое,однако код не имеет смысла, если я на самом деле не считаю его отрицательным числом.Я дважды проверил код операции, посмотрев его на en.wikipedia.org/wiki/MIPS_architecture.И это действительно «addiu», а не «addi».Я так запутался здесь.

1 Ответ

2 голосов
/ 27 июля 2011

Первые три инструкции предназначены для поддержки Независимый от позиции код .См. на этой странице linux-mips для превосходного объяснения PIC на MIPS.t9 содержит адрес функции, который может меняться каждый раз, когда вы загружаете библиотеку, поддерживающую PIC, и это значение добавляется к константе уже в gp.Аналогично x86:

call __i686.get_pc_thunk.bx
add $0x1b88, %ebx

Где __i686.get_pc_thunk.bx загружает %ebx с адресом следующей инструкции, а последующее добавление преобразует %ebx в точку отсчета, которая будет использоваться для доступа к глобальным символам.

ADDIU: Единственное отличие между подписанным и неподписанным дополнением в MIPS заключается в том, что добавление со знаком может вызвать исключение переполнения, поэтому вместо этого используется ADDIU.

Несколько настроек стека: Это, вероятно, связано с тем, что MIPS использует 16-битные непосредственные значения, поэтому не всегда можно отрегулировать стек за один ADDIU.

...