У меня есть следующий код сборки ARM. Цель состоит в том, чтобы распечатать 32-разрядное целое число в шестнадцатеричном символе за символом. Прототипом функции для этой функции сборки является printx(int, int)
, где первый int
- это целое число, которое будет напечатано, а второй - флаг, указывающий, следует ли печатать его в верхнем или нижнем регистре. Переменные данных существуют, когда я сам пытался отладить код, сравнивая вывод printf и вывод моего кода.
.data
derp: .asciz "\nDerp\n"
hex: .asciz "HEX %x\n"
dec: .asciz "\nDEC %d\n"
count: .asciz "\nCOUNT %d\n"
.text
.global printx
printx:
push {fp, lr}
mov fp, sp
mov r11, #1 // firstloop counter "i"
firstloop: // loop to extract hex character
cmp r11, #1 // if i == 1
beq endsecond // jump to end of loop (no shift necessary)
lsr r0, r0, #4 // logical shift right 4 bits
endsecond:
and r4, r0, #0xf // gets first 4 bits
cmp r4, #9 // is it greater than 9?
bgt alpha // jump to alpha
add r4, r4, #48 // add 48 to get ascii for number
b beta // jump to beta
alpha:
cmp r1, #1 // if uppercase flag is set
beq upper // jump to upper
add r4, r4, #87 // add 87 to get ascii for lowercase letters
b beta // jump to beta
upper:
add r4, r4, #55 // add 55 to get ascii for uppercase letters
beta:
push {r4} // push ascii character onto stack
cmp r11, #8 // if i == 8
beq popping // branch to popping
add r11, #1 // i++
b firstloop // branch to firstloop
popping:
mov r10, #1 // let r9 indicate leading (1 is true)
poploop:
pop {r0} // pop into r5
cmp r0, #0 // if r5 != 0
bne nonzero // branch to nonzero
cmp r10, #1 // if r10 == 1 (if leading)
beq counter // branch to counter
b print // branch to print
nonzero:
mov r10, #0 // set leading (r10) to false (0)
print:
bl putchar // call putchar
counter:
sub r11, #1 // i--
cmp r11, #0 // if i != 0
bne poploop // branch to poploop
ldr r0, =derp
bl printf
mov sp, fp
pop {fp, pc}
.end
Когда я запускаю gdb
, я получаю следующее:
Program received signal SIGSEGV, Segmentation fault.
counter () at printinteger.s:62
62 pop {fp, pc}
Я дважды проверил, что я выталкиваю ровно столько раз, сколько выталкиваю в стек, поэтому я думаю, что это может иметь какое-то отношение к тому, как я выталкиваю указатель кадра и счетчик программы на основе на GDB, или я перемещаю указатель стека в неправильном месте. Буду признателен за любую помощь в диагностике проблемы.