Почему функция прерывания программы номер 4 linux 0x80 (sys_write) в массиве символов не работает?

Я хочу вывести строку в стандартный вывод, вызвав прерывание linux 0x80, но когда я использую массив символов в качестве аргумента, он не может производить вывод.

Когда я использую переменную указателя char в качестве параметра, проблем нет.

Это мой код (файл: c.c). На выходе выведите «cd», а не «abcd».

void prints(char *str, int size){
    asm(
        "movl $4, %%eax \n\t"
        "movl $1, %%ebx \n\t"
        "movl %0, %%ecx \n\t"
        "movl %1, %%edx \n\t"
        "int $0x80 \n\t"
        ::"m"(str), "m"(size)
       );

    return;
}

int main(){
    char str[] = {'a', 'b', '\0'};
    char *str1 = "cd";
    prints(str, 3);
    prints(str1, 3);
}

Я использую gcc -S c.c, выходной файл примерно такой. Я до сих пор не могу понять, почему не выводится "ab".

    .file   "c.c"
    .text
.globl prints
    .type   prints, @function
prints:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movq    %rdi, -8(%rbp)
    movl    %esi, -12(%rbp)
#APP
# 2 "c.c" 1
    movl $4, %eax 
    movl $1, %ebx 
    movl -8(%rbp), %ecx 
    movl -12(%rbp), %edx 
    int $0x80 

# 0 "" 2
#NO_APP
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   prints, .-prints
    .section    .rodata
.LC0:
    .string "cd"
    .text
.globl main
    .type   main, @function
main:
.LFB1:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movb    $97, -16(%rbp)
    movb    $98, -15(%rbp)
    movb    $0, -14(%rbp)
    movq    $.LC0, -8(%rbp)
    leaq    -16(%rbp), %rax
    movl    $3, %esi
    movq    %rax, %rdi
    call    prints
    movq    -8(%rbp), %rax
    movl    $3, %esi
    movq    %rax, %rdi
    call    prints
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1:
    .size   main, .-main
    .ident  "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-18)"
    .section    .note.GNU-stack,"",@progbits

Потому что вы генерируете 64-битный код и используете 32-битные указатели и 32-битный интерфейс системного вызова (int 0x80). Указатель стека, в котором хранится ab\0, не может быть представлен в 32-битном указателе. Вам нужно (и нужно) использовать syscall для 64-битного кода вместо int $0x80. Для получения дополнительной информации об использовании syscall см. Блог Райана Чепмена

Michael Petch 03.06.2018 16:31

Вдобавок к моему последнему комментарию вам также нужно быть осторожным. Если ваша встроенная сборка изменяет значения регистров, она должна сообщить об этом компилятору. Либо используйте правильные ограничения вывода (или ввода / вывода), либо перечислите их как clobbers.

Michael Petch 03.06.2018 16:34
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
31
0

Другие вопросы по теме