Я пытаюсь написать программу на ассемблере, которая пишет весь char** argv
контент. В C это будет так:
#include <stdio.h>
int main(int argc, char** argv) {
for (unsigned int i = 0; argv[i] != 0; i++)
puts(argv[i]);
return 0;
}
и я написал это в сборке так:
.global main
.data
.bss
.text
.align 4
@r0 = argc
@r1 = argv
main:
@prologue
stmfd sp!, {fp, lr}
add fp, sp, #4
sub sp, sp, #8
@i = 0
mov r0, #0
str r0, [fp, #-8]
b loop_begin
loop_content:
bl puts
ldr r0, [fp, #-8]
add r0, r0, #1
str r0, [fp, #-8]
loop_begin:
@r0 = i
ldr r0, [fp, #-8]
@i = i * 4
lsl r0, r0, #2
@r0 = argv + i
add r0, r1, r0
@r3 = argv[i]
ldr r0, [r0]
@argv[i] == 0?
cmp r0, #0
@if arvg[i] != 0 go to ...
bne loop_content
mov r0, #0
sub sp, fp, #4
ldmfd sp!, {fp, lr}
bx lr
но это дает мне segfault в
str r0, [fp, #-8]
Понятия не имею, почему, у вас есть идеи, почему это происходит?
char** envp
, так что это условие более уникальное :) - person Mattern   schedule 10.12.2019add r9, r9, #1
, сразу послеbl puts
, из-за этого я думаю, чтоbl puts
может вызвать ошибку, но нет очевидных причин, почему - person Mattern   schedule 10.12.2019add
не может быть виновато. Скорее всего, вы неправильно использовали gdb. В вашем коде есть проблемы, например, полагаться на то, что значение вr1
сохраняется при вызовах. На самом деле, просто исправление заставляет меня работать. - person Jester   schedule 10.12.2019r1
? - person Mattern   schedule 10.12.2019bl puts
уничтожит его. Вам нужно будет сохранить его самостоятельно. - person Jester   schedule 10.12.2019mov r1, r8
перед звонком иmov r8, r1
сразу после, и это помогло! Большое спасибо! Вы можете ответить на вопрос, чтобы я мог отметить его как правильный ответ - person Mattern   schedule 10.12.2019bl puts
сохраняетr8
для вас, вы также должны сохранить его для вызывающего абонента (в данном случае код libc). - person Jester   schedule 10.12.2019argv[]
- массив указателей с завершающим нулем. (argv[argc] == NULL
) Код C безопасен. - person Peter Cordes   schedule 11.12.2019