Chapter 20
Page 449
-
I chose my
addFloats
andrecordField
programs.Breakpoint 1, main () at addFloats.s:23 23 push rbp # save frame pointer (gdb) i r rip rsp rip 0x555555555159 0x555555555159 <main> rsp 0x7fffffffde78 0x7fffffffde78
Breakpoint 1, main () at recordField.s:22 22 push rbp # save frame pointer (gdb) i r rip rsp rip 0x555555555139 0x555555555139 <main> rsp 0x7fffffffde98 0x7fffffffde98
The addresses in the
rsp
andrip
register differ by only 32 bytes, which looks like they’re running in the same place in memory. But these are virtual memory addresses. The operating system loads the two programs in different physical memory locations and uses the page map table to translate between the two memory address spaces.
Page 459
-
Well, I did try to run the program. The operating system gave me an error message:
$ gcc -c -O0 -Wall -masm=intel -g UART_functions.c $ gcc -c -O0 -Wall -masm=intel -g UART_echo.c $ ld -e myProg -o UART_echo UART_echo.o UART_functions.o $ ./UART_echo Segmentation fault (core dumped) ```
The operating system prevents us from accessing I/O directly from a user program.
-
As with the C version, the operating system prvents us from accessing I/O.
as --gstabs -o UART_functions.o UART_functions.s ld -e myProg -o UART_echo UART_echo.o UART_functions.o $ ./UART_echo Segmentation fault (core dumped)
Page 463
-
We need to use the base UART port address for the port-mapped version.
/* UART_echo.c * Use a UART to echo a single character. * WARNING: This code does not run on any known * device. It is meant to sketch some * general I/O concepts only. */ #include "UART_functions.h" #define UART0 (unsigned short int)0x3f8 /* location of UART */ int myProg() { unsigned char aCharacter; UART_init(UART0); aCharacter = UART_in(UART0); UART_out(UART0, aCharacter); return 0; }
/* UART_functions.h * Initialize, read, and write functions for an abstract UART. * WARNING: This code does not run on any known * device. It is meant to sketch some * general I/O concepts only. */ #ifndef UART_FUNCTIONS_H #define UART_FUNCTIONS_H void UART_init(unsigned short int UART); /* initialize UART */ unsigned char UART_in(unsigned short int UART); /* input */ void UART_out(unsigned short int UART, unsigned char c); /* output */ #endif
# UART_functions.s # Initialize, read, and write functions for an abstract UART. # WARNING: This code does not run on any known # device. It is meant to sketch some # general I/O concepts only. .intel_syntax noprefix .include "UART_defs" # Intialize the UART # Calling sequence: # rdi <- base port of UART .text .globl UART_init .type UART_init, @function UART_init: push rbp # save frame pointer mov rbp, rsp # set new frame pointer # no interrupts, don't use FIFO queue lea dx, IER[rdi] # interrupt enable port mov al, NOINTERRUPT out dx, al lea dx, FCR[rdi] # FIFO control port mov al, NOFIFO out dx, al # set divisor latch access bit = 1 to set baud lea dx, LCR[rdi] # line control port mov al, SETBAUD out dx, al lea dx, DLM[rdi] # divisor high-order byte mov al, MSB38400 out dx, al lea dx, DLL[rdi] # divisor low-order byte mov al, LSB38400 out dx, al # divisor latch access bit = 0 for communications mode lea dx, LCR[rdi] # line control port mov al, SETCOM out dx, al mov rsp, rbp # yes, restore stack pointer pop rbp # and caller frame pointer ret # Input a single character # Calling sequence: # rdi <- base address of UART # returns character in al register .globl UART_in .type UART_in, @function UART_in: push rbp # save frame pointer mov rbp, rsp # set new frame pointer inWaitLoop: lea dx, LSR[rdi] # line status port in al, dx and al, RxRDY # character ready? jne inWaitLoop # no, wait lea dx, RBR[rdi] # yes, receiver buffer in al, dx # get character mov rsp, rbp # restore stack pointer pop rbp # and caller frame pointer ret # Output a single character in sil register # Calling sequence: # rdi <- base address of UART # sil <- character to output .globl UART_out .type UART_out, @function UART_out: push rbp # save frame pointer mov rbp, rsp # set new frame pointer outWaitLoop: lea dx, LSR[rdi] # line status port in al, dx and al, TxRDY # ready for character? jne inWaitLoop # no, wait lea dx, THR[rdi] # yes, transmitter holding mov al, sil # need character in al out dx, al # send character mov rsp, rbp # restore stack pointer pop rbp # and caller frame pointer ret