uart sending in 8051 - math

In uart, I tried to sent in some numbers that Itried to convert to bcd and then to send.
The code works only from 00 to 99, if I want to send something bigger then 99 it will convert it to an ASCI table to some char or different number.
Could you help me to improve it so that I can to send numbers up to 255?
print_arr:
mov a,#r0
anl a ,#0f0h
swap a
add a , #30h
mov sbuf , a
jnb ti , $
clr ti
mov a , #r0
anl a ,#0fh
add a , #30h
mov sbuf , a
jnb ti , $
clr ti
mov sbuf ,#' ';
jnb ti,$
clr ti
inc r0
djnz r7,print_arr
mov a , #0DH
mov sbuf , a
jnb TI , $
clr TI
mov a , #0AH
mov sbuf , a
jnb TI , $
clr TI
clr TR1
ret
end

Related

How do you correctly debug A/D convertor code in MPLAB X v5.05 simulator

This is a continuation of the question posed in How do you run a SCL file in MPLAB without a "Run SCL" button
I have an assembly code for PIC18F458 that gets data from channel 0 (RA0) of ADC and displays the result on PORTC and PORTD.
Although, I have managed to verify that the code operates as desired within Proteus, I am struggling to do the same within the MPLAB X simulator environment using a SCL file, and I suspect that this is due to the way that the text files, referred to by it, are laid out. (Please see below)
testbench for "pic18f458" is
begin
process is
file datafile : text;
variable intVar : integer;
variable sampling_voltage : integer;
variable fileStatus : file_open_status;
variable fileLine : line;
begin
loop
report("Analog injection started...");
file_open(fileStatus, datafile, "text2.txt", read_mode);
if fileStatus == open_ok then
report("Reading the values file...");
while endfile(datafile) == false loop
wait until ADCON0.GO_nDONE == '1';
report("Conversion started");
readline(datafile, fileLine);
wait for 400 ns;
read(fileLine, intVar);
sampling_voltage := intVar; -- sample input voltage
wait until ADCON0.GO_nDONE == '0';
report("Conversion ended");
if ADCON1.ADFM == '0' then -- left justified
ADRESH <= sampling_voltage / 4;
ADRESL <= sampling_voltage * 64;
else -- right justified
ADRESH <= sampling_voltage / 256;
ADRESL <= sampling_voltage;
end if;
end loop;
file_close(datafile);
end if;
end loop;
wait;
end process;
end testbench;
The SCL file refers to 1 of 2 text files during my debugging session (text.txt and text2.txt) laid out differently. The first consists of decimal numbers from 0 to 255 and the second consists of decimal numbers representing voltages in mV.
txt.txt
128
192
238
255
238
192
128
64
17
0
17
64
128
text2.txt
250 mV
500 mV
750 mV
1000 mV
1250 mV
1500 mV
1750 mv
2000 mV
2250 mv
2500 mv
2750 mv
3000 mv
3250 mV
3500 mV
3750 mV
4000 mV
4250 mV
4500 mV
4750 mv
5000 mV
In both cases, the ADC seems to just be churning out the numbers that it is receiving, instead of converting them. (Please see images below)
This is obviously no good, as I am getting values within the ADRES register that are greater than 10-bits, in particularly, with regards to my text2.txt values.
ADC Results with text.txt
ADC Results with text2.txt
Therefore, my question is how do I correctly debug my A/D convertor code in MPLAB X v5.05 simulator using a SCL file or any other methods?

Why an ELF executable could have 4 LOAD segments?

There is a remote 64-bit *nix server that can compile a user-provided code (which should be written in Rust, but I don't think it matters since it uses LLVM). I don't know which compiler/linker flags it uses, but the compiled ELF executable looks weird - it has 4 LOAD segments:
$ readelf -e executable
...
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
...
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000004138 0x0000000000004138 R 0x1000
LOAD 0x0000000000005000 0x0000000000005000 0x0000000000005000
0x00000000000305e9 0x00000000000305e9 R E 0x1000
LOAD 0x0000000000036000 0x0000000000036000 0x0000000000036000
0x000000000000d808 0x000000000000d808 R 0x1000
LOAD 0x0000000000043da0 0x0000000000044da0 0x0000000000044da0
0x0000000000002290 0x00000000000024a0 RW 0x1000
...
On my own system all executables that I was looking at only have 2 LOAD segments:
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
...
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x00000000003000c0 0x00000000003000c0 R E 0x200000
LOAD 0x00000000003002b0 0x00000000005002b0 0x00000000005002b0
0x00000000000776c8 0x000000000009b200 RW 0x200000
...
What are the circumstances (compiler/linker versions, flags etc) under which a compiler might build an ELF with 4 LOAD segments?
What is the point of having 4 LOAD segments? I imagine that having a segment with read but not execute permission might help against certain exploits, but why have two such segments?
A typical BFD-ld or Gold linked Linux executable has 2 loadable segments, with the ELF header merged with .text and .rodata into the first RE segment, and .data, .bss and other writable sections merged into the second RW segment.
Here is the typical section to segment mapping:
$ echo "int foo; int main() { return 0;}" | clang -xc - -o a.out-gold -fuse-ld=gold
$ readelf -Wl a.out-gold
Elf file type is EXEC (Executable file)
Entry point 0x400420
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x0001f8 0x0001f8 R 0x8
INTERP 0x000238 0x0000000000400238 0x0000000000400238 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0006b0 0x0006b0 R E 0x1000
LOAD 0x000e18 0x0000000000401e18 0x0000000000401e18 0x0001f8 0x000200 RW 0x1000
DYNAMIC 0x000e28 0x0000000000401e28 0x0000000000401e28 0x0001b0 0x0001b0 RW 0x8
NOTE 0x000254 0x0000000000400254 0x0000000000400254 0x000020 0x000020 R 0x4
GNU_EH_FRAME 0x00067c 0x000000000040067c 0x000000000040067c 0x000034 0x000034 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
GNU_RELRO 0x000e18 0x0000000000401e18 0x0000000000401e18 0x0001e8 0x0001e8 RW 0x8
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .dynsym .dynstr .gnu.hash .hash .gnu.version .gnu.version_r .rela.dyn .init .text .fini .rodata .eh_frame .eh_frame_hdr
03 .fini_array .init_array .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag
06 .eh_frame_hdr
07
08 .fini_array .init_array .dynamic .got .got.plt
This optimizes the number of mmaps that the kernel must perform to load such executable, but at a security cost: the data in .rodata shouldn't be executable, but is (because it's merged with .text, which must be executable). This may significantly increase the attack surface for someone trying to hijack a process.
Newer Linux systems, in particular using LLD to link binaries, prioritize security over speed, and put ELF header and .rodata into the first R-only segment, resulting in 3 load segments and improved security. Here is a typical mapping:
$ echo "int foo; int main() { return 0;}" | clang -xc - -o a.out-lld -fuse-ld=lld
$ readelf -Wl a.out-lld
Elf file type is EXEC (Executable file)
Entry point 0x201000
There are 10 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000200040 0x0000000000200040 0x000230 0x000230 R 0x8
INTERP 0x000270 0x0000000000200270 0x0000000000200270 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000558 0x000558 R 0x1000
LOAD 0x001000 0x0000000000201000 0x0000000000201000 0x000185 0x000185 R E 0x1000
LOAD 0x002000 0x0000000000202000 0x0000000000202000 0x001170 0x002005 RW 0x1000
DYNAMIC 0x003010 0x0000000000203010 0x0000000000203010 0x000150 0x000150 RW 0x8
GNU_RELRO 0x003000 0x0000000000203000 0x0000000000203000 0x000170 0x001000 R 0x1
GNU_EH_FRAME 0x000440 0x0000000000200440 0x0000000000200440 0x000034 0x000034 R 0x1
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0
NOTE 0x00028c 0x000000000020028c 0x000000000020028c 0x000020 0x000020 R 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .rodata .dynsym .gnu.version .gnu.version_r .gnu.hash .hash .dynstr .rela.dyn .eh_frame_hdr .eh_frame
03 .text .init .fini
04 .data .tm_clone_table .fini_array .init_array .dynamic .got .bss
05 .dynamic
06 .fini_array .init_array .dynamic .got
07 .eh_frame_hdr
08
09 .note.ABI-tag
Not to be left behind, the newer BFD-ld (my version is 2.31.1) also makes ELF header and .rodata read-only, but fails to merge two R-only segments into one, resulting in 4 loadable segments:
$ echo "int foo; int main() { return 0;}" | clang -xc - -o a.out-bfd -fuse-ld=bfd
$ readelf -Wl a.out-bfd
Elf file type is EXEC (Executable file)
Entry point 0x401020
There are 11 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x000268 0x000268 R 0x8
INTERP 0x0002a8 0x00000000004002a8 0x00000000004002a8 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0003f8 0x0003f8 R 0x1000
LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x00018d 0x00018d R E 0x1000
LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x000110 0x000110 R 0x1000
LOAD 0x002e40 0x0000000000403e40 0x0000000000403e40 0x0001e8 0x0001f0 RW 0x1000
DYNAMIC 0x002e50 0x0000000000403e50 0x0000000000403e50 0x0001a0 0x0001a0 RW 0x8
NOTE 0x0002c4 0x00000000004002c4 0x00000000004002c4 0x000020 0x000020 R 0x4
GNU_EH_FRAME 0x002004 0x0000000000402004 0x0000000000402004 0x000034 0x000034 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
GNU_RELRO 0x002e40 0x0000000000403e40 0x0000000000403e40 0x0001c0 0x0001c0 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn
03 .init .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .init_array .fini_array .dynamic .got .got.plt .data .bss
06 .dynamic
07 .note.ABI-tag
08 .eh_frame_hdr
09
10 .init_array .fini_array .dynamic .got
Finally, some of these choices are affected by the --(no)rosegment (or -Wl,z,noseparate-code for BFD ld) linker option.

Values of a register after executing code

What are the values of r16 and r17 after executing this code?
ldi r16, 0x06 ;load immediate
ldi r17, 0x0c ;load immediate
lsl r16 ;logical shift left
eor r16, r17 ;exclusive or
So I know that r16 = 12 after the logical shift left, making it equal to r17. Does the exclusive or set r16 to 0 and r17 stays at 12? Or do they both get set to zero? Is the zero flag set?
From the obvious source, http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_instructions.Arithmetic_and_Logic_Instructions.html :
EOR Logical Exclusive OR
Rd = Rd EOR Rr
So yes, r16 gets overwritten, but r17 stays unchanged.
http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_EOR.html
even spezifies what happens with the Zero Flag in the status register: It's set to (¯ denoting the inverse,• denoting logical and)
R7¯ • R6¯ • R5¯ • R4¯ • R3¯ • R2¯ • R1¯ • R0¯

Edsim51 Always Invalid Label Error

I'm using EDSIM51 on MacOS. But I'm always getting Invalid Label - **** is keyword errors. Read documentation (User's Guide and Examples pages) but still no idea where I'm making mistake. I've downloaded example codes from Edsim's website, but it's giving same error for their official examples.
For example,
This is an LCD example which taken from their website:
; put data in RAM
MOV 30H, #'A'
MOV 31H, #'B'
MOV 32H, #'C'
MOV 33H, #0 ; end of data marker
; initialise the display
; see instruction set for details
CLR P1.3 ; clear RS - indicates that instructions are being sent to the module
; function set
CLR P1.7 ; |
CLR P1.6 ; |
SETB P1.5 ; |
CLR P1.4 ; | high nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
CALL delay ; wait for BF to clear
; function set sent for first time - tells module to go into 4-bit mode
; Why is function set high nibble sent twice? See 4-bit operation on pages 39 and 42 of HD44780.pdf.
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
; same function set high nibble sent a second time
SETB P1.7 ; low nibble set (only P1.7 needed to be changed)
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
; function set low nibble sent
CALL delay ; wait for BF to clear
; entry mode set
; set to increment with no shift
CLR P1.7 ; |
CLR P1.6 ; |
CLR P1.5 ; |
CLR P1.4 ; | high nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
SETB P1.6 ; |
SETB P1.5 ; |low nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
CALL delay ; wait for BF to clear
; display on/off control
; the display is turned on, the cursor is turned on and blinking is turned on
CLR P1.7 ; |
CLR P1.6 ; |
CLR P1.5 ; |
CLR P1.4 ; | high nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
SETB P1.7 ; |
SETB P1.6 ; |
SETB P1.5 ; |
SETB P1.4 ; | low nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
CALL delay ; wait for BF to clear
; send data
SETB P1.3 ; clear RS - indicates that data is being sent to module
MOV R1, #30H ; data to be sent to LCD is stored in 8051 RAM, starting at location 30H
loop:
MOV A, #R1 ; move data pointed to by R1 to A
JZ finish ; if A is 0, then end of data has been reached - jump out of loop
CALL sendCharacter ; send data in A to LCD module
INC R1 ; point to next piece of data
JMP loop ; repeat
finish:
JMP $
sendCharacter:
MOV C, ACC.7 ; |
MOV P1.7, C ; |
MOV C, ACC.6 ; |
MOV P1.6, C ; |
MOV C, ACC.5 ; |
MOV P1.5, C ; |
MOV C, ACC.4 ; |
MOV P1.4, C ; | high nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
MOV C, ACC.3 ; |
MOV P1.7, C ; |
MOV C, ACC.2 ; |
MOV P1.6, C ; |
MOV C, ACC.1 ; |
MOV P1.5, C ; |
MOV C, ACC.0 ; |
MOV P1.4, C ; | low nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
CALL delay ; wait for BF to clear
delay:
MOV R0, #50
DJNZ R0, $
RET
**AND ERROR : ** Invalid Label - FİNİSH is keyword
Can you please tell me what is I'm missing?

About MPEG-4 headers

I examined some MPEG-4 video headers and saw some byte arrays like below at the beginning:
00 00 01 B0 01 00 00 01 B5 89 13
I know 00 00 01 parts but what exactly B0 B1 and B5 89 13 parts mean? Actually, if I put this byte array infront of an MPEG-4 stream, it works fine.
But I don't know if those values works with different mpeg-4 stream sources ?
0x000001B0 -> Visual Object Sequence Start (VOSS) Code
0x000001B5 -> Visual Object Start (VOS) Code
You can find the complete MPEG-4 elementary video header details at "ISO/IEC 14496-2" documentation. Here are the details you asked for.
Visual Object Sequence Start (VOSS) Code
-> 4 bytes visual object sequence start code = long hex value of 0x000001B0
-> 8 bits profile/level indicator = 1 byte unsigned number
Visual Object Start (VOS) Code
-> 4 bytes visual object start code = long hex value of 0x000001B5
-> 1 bit has id marker flag = 1/4 nibble flag
_ID_Marker_Section_
-> 4 bits version id = 1 nibble unsigned value - only if marker is true
- version id types are ISO 14496-2 = 1
-> 3 bits visual object priority = 3/4 nibble unsigned value - only if marker is true
- priorities are 1 through to 7
-> 4 bits visual object type = 1 nibble unsigned value
- types are video = 1 ; still texture = 2 ; mesh = 3 ; face = 4
-> 1 bit video signal type = 1/4 nibble flag
- NOTE: if this is false Y has a sample range of 16 through to 235

Resources