Как компьютер различает число и символ? - PullRequest
0 голосов
/ 26 апреля 2018

На основании таблицы ASCII, когда мы сохраняем «TAB» и десятичное 9 в памяти, они оба сохраняются как «1001». Как компьютер узнает, что это «TAB» или десятичное число 9?

Ответы [ 3 ]

0 голосов
/ 28 апреля 2018

Позвольте мне использовать почтенного VAX в качестве примера. Предположим, вы определили 8 байт памяти в каком-то месте:

location:
     .ASCII /ABCDEFGH/

Инструкция

 MOVC3   location, 8, some_other_location

обрабатывает память как символы.

Инструкция

ADDL2 location, R0

обрабатывает ту же память как целочисленное значение

Инструкция

MULD2 location, R8

обрабатывает ту же память как значение с плавающей запятой.

Инструкция:

jmp location

обрабатывает ту же память, что и код (но, вероятно, вырвет).

Память - это память. Как это интерпретируется, зависит от инструкции, работающей с памятью. Компьютер не знает, что хранится в каком-либо месте. Это решать программисту.

0 голосов
/ 04 мая 2018

Нет никакой разницы между текстовыми данными или любыми другими типами данных как таковыми, поэтому компьютер не может различить ASCII-символ или простое число в памяти.

Однако, процесс , действующий на этих данных, обрабатывает различное содержимое памяти по-разному и поставляется со «знанием» типа данных, вставленных в его последовательность команд. Например, для вызова printf () аргумент должен быть строкой символов (символьная строка с нулевым символом в конце). Итак, у вас это есть, знания в процессе, а не данные.

Это может привести к проблемам, потому что программист должен убедиться, что правильные типы аргументов (данных) переданы определенной функции (процессу). - К счастью, компиляторы (и другие помощники, используемые во время разработки во время время компиляции или раньше, например, с помощью статический анализ ), также "знают", как вещи должны быть напечатаны (в случае строго типизированные языки ), поэтому неисправная программа обычно не компилируется. - Но в любом случае, например, в C, вы можете обрабатывать любое содержимое памяти как любой тип данных, который вы хотели бы (например, приведение типа ), с некоторыми ограничениями, даже как исполняемый код.

Во время выполнения (почти) ничто не мешает программе интерпретировать данные в произвольной ячейке памяти как текст ASCII или простые числа, это просто вопрос представления.

Однако существуют соглашения о том, как программа структурирована и где она хранит текст в виде статических строк, известных во время компиляции, то есть в виде простого текста. Обычно они помещаются в сегмент .data или .rodata программы (обычно не в сегменте .text). Вы можете сканировать двоичную программу, используя строки , например:

$ strings /usr/bin/strings

Или, если вы хотите узнать больше о сегментах .data / .rodata, вам может пригодиться binutils '1032 * objdump :

$ objdump -h /usr/bin/strings
$ objdump --full-contents --section .rodata /usr/bin/strings

То же самое можно сделать с помощью шестнадцатеричного редактора:

$ xxd <my-binary>
$ xxd /usr/bin/strings

В конце концов, каждая программа должна знать , как обращаться с ее памятью и как интерпретировать отдельные биты двоичных данных в ней. Программа обычно выполняется внутри операционной системы, которая определяет другие типы ограничений в отношении того, какие области памяти доступны и как, и программа может взаимодействовать с другими процессами вне или внутри коробки (разрешения на доступ, системные API, которые требуют определенный тип данных, например, текстовые или двоичные данные). Но опять же, в этом случае знания также лежат в процессах, а не в самих данных. Аппаратные средства (то есть процессор и память (RAM, FLASH ...)) не обрабатывают текстовые данные принципиально иначе, чем другие типы данных.

0 голосов
/ 26 апреля 2018

Компьютер не «знает», какой тип является конкретным адресом в памяти, эти знания включаются в инструкции вашей программы.

Когда вы пишете программу и она видит вашу переменную, компилятор создает ассемблерный код, который записывает этот фрагмент данных куда-то, а где-то еще есть некоторый другой код, который читает адрес памяти и интерпретирует его как символ . Знание, что это является символом, не сохраняется в памяти. Расположение этого адреса памяти - единственное, что связывает эти две операции вместе.

Когда это местоположение читается, сборка не говорит «посмотрите, какой тип данных там», она просто говорит «загрузите это расположение памяти и рассматривайте его как символ». Например, если что-то перезаписало этот адрес памяти чем-то другим, а не символом, ЦП все равно просто загрузит эту память как символ, и в результате могут произойти любые странные вещи.

Например, в следующей программе:

#include <stdio.h>

int main()
{
    int x; 
    x = 9;
    char* y;
    y = &x;
    printf("\"%s\" \"%d\"\n", y, x);
    printf("%p\n%p", y, &x);
    return 0;
}

Вы получите вывод как:

"       " "9"                                                                                                                                                                                                                                    
0x7ffd401ce68c                                                                                                                                                                                                                                   
0x7ffd401ce68c

Итак, мы видим, что то же самое местоположение в памяти обрабатывается как char и как int. Значение в памяти не знает и не заботится о том, как оно используется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...