2012-04-08 2 views
2

В конце дня каждый фрагмент кода, который мы пишем, в конечном итоге превращается в ассемблер, а затем машинный язык.Что означает машинный код для сетей?

Если вы писали ассемблер и хотите выполнить простую связь между двумя компьютерами, как вы узнаете, какие адреса памяти использовать (не говоря уже о смещениях) внутри ассемблера? Вам нужно знать конкретные адреса, относящиеся к операционной системе?

Мне просто интересно, как кто-нибудь напишет действительно «чистое» и «эффективное» сообщение, передающее библиотеку/компилятор, - вещь, которая меня достает, - это то, что на самом деле сетевые коммуникации/IPC выглядят как на ассемблере?

Я думаю, что часть этого ответа может заключаться в запросе известных адресов, относящихся к ОС? Например, 0x4545456 до 0x 60000000 содержит данные ядра ядра Linux для связи X и т. Д.

+0

Это очень общий вопрос, поэтому я дал вам очень длинный общий ответ. Если бы вы были более конкретными, вы получили бы более конкретный ответ. Ассемблер автоматически не подразумевает чистоту/эффективность, это сложнее, чем это. –

ответ

1

Адреса не относятся к вашей ОС. Они специфичны для вашего оборудования/системы. Доступ к ним не имеет ничего общего с ассемблером и другим языком программирования (например, C), на самом деле большинство кода драйвера устройства (код, который фактически взаимодействует с сетевым оборудованием) обычно записывается в C.

Вот только один случайный образец из сети (Ethernet) контроллера:

Intel® 82580EB/82580DB GbE Controller: Datasheet

есть куча регистров, что ваше программное обеспечение, либо на ассемблере, или на другом языке, должен запрограммировать, чтобы получить эту вещь на самом деле общаться через сеть Ethernet. Наверное, проще начать с более простого примера, похожего на последовательный порт.Давайте строить гипотетические, фиксированную скорость передачи данных, контроллер последовательного порта, отображенный в память:

Address Meaning 
0  RX status (reads 0 when no data to read, 1 a byte is available) 
1  RX buffer 
2  TX status (reads 0 when ready to send, 1 when busy) 
3  TX buffer 

Теперь ваше программное обеспечение, либо на ассемблере или на любом другом языке, могут передавать данные на другой компьютер, с помощью мониторинга (опроса) Адрес 2 пока он не будет готов, записывая следующий байт на адрес 3. Мы также можем получать данные с другого компьютера путем мониторинга (опроса) адреса 0, чтобы видеть, когда данные готовы и чтение байта с адреса 1, когда данные есть.

В современной операционной системе/ОС это все физические адреса, которые необходимо каким-то образом отобразить в виртуальные адреса.

Оборудование реального мира, например, связанное с ним, обычно будет использовать прерывания, поэтому вам не нужно опроса. Обычно он имеет DMA, поэтому аппаратное обеспечение может напрямую обращаться к вашим данным, а не кормить его байтом байтом. Он будет обрабатывать различные протоколы и будет иметь регистры для проверки и настройки различных аспектов этого протокола.

В современной ОС фактическое взаимодействие с оборудованием реализовано в device driver, и пользовательское программное обеспечение может обмениваться данными с драйвером устройства через некоторый API. Опять же, этот код пользователя может быть написан на ассемблере или на любом другом языке. API будет отличаться в зависимости от ОС. Коммуникация/сеть обычно построена как «stack» с протоколами более высокого уровня, реализованными на более низких уровнях. Какая часть этого стека находится в пользовательской библиотеке или часть ОС будет различаться между различными операционными системами.

Для гипотетического устройства, описанного выше, API может состоять из двух одиночных байтовых вызовов, read() и write(). Затем вы используете какой-то механизм system call либо на ассемблере, либо на языке более высокого уровня, чтобы вызвать их и передать параметры/получить результат. В некоторых операционных системах устройство ввода-вывода может выглядеть как файловый ввод-вывод, поэтому вы должны использовать общий файл для чтения/записи для выполнения операций на устройстве, и ОС отправит их в нужное устройство. Кроме того, в типичной ОС фактический системный вызов будет доступен через какую-то библиотеку, которую вы также можете вызвать из разных языков программирования.

0

Существует два кода кода для создания сетей в сборке - код ядра, используемый операционной системой для фактической работы сети и клиентский код, который хочет сообщить ОС, какие данные отправлять по сети.

Как правило, аппаратное обеспечение в аппарате имеет определенные адреса памяти, предназначенные для связи с сетевым оборудованием. Затем машинный код ОС может записать соответствующие значения в эту память для управления оборудованием, которое заканчивает отправку и получение байтов. Эти адреса памяти будут жестко закодированы в машинный код.

В случае кода пользователя, который работает в сети (скажем, Mozilla Firefox), процесс отличается. Как правило, машинная инструкция или набор инструкций, которые используются для кода пользователя, указывают операционной системе на выполнение какой-либо задачи (например, в MIPS это syscall, в то время как я думаю, что x86 использует команду int). Клиентский код будет работать, настроив некоторые буферы с соответствующими данными для отправки в сеть, а затем использовал бы одну из приведенных выше инструкций по сборке, чтобы сообщить ОС, что она должна отправлять данные. Затем аппаратное обеспечение вызывает ОС, которая считывает пользовательские данные, а затем использует свой собственный машинный код (описанный выше) для фактического управления сетевым устройством. Таким образом, ОС может защищать прямой доступ к сетевому устройству, блокируя доступ к физическим адресам, управляющим устройством, и модерируя доступ через системные вызовы. Это также означает, что вам не нужно знать какие-либо адреса памяти при написании кода пользователя для создания сети. ОС обрабатывает эти данные, и все, что вам нужно знать, - это какая инструкция выполнить для запуска системного вызова.

Надеюсь, это поможет!

Смежные вопросы