"can't find label" error in Y86 compiler - compilation

I'm writing up a program in Y86, but I keep getting an error "can't find label" for my code lines setting up the stack and base pointer. My code is:
.pos 0
init:
irmovl Stack, %esp //Set up stack pointer
irmovl Stack, %ebp //Set up base pointer
call main //call main program
halt //Terminate program
Which is how it appears in my notes, but when I try to compile, I get
Error on line 8: Can't find label
Line 8, Byte 0x0006: irmovl stack, %esp //Set up stack pointer
Error on line 9: Can't find label
Line 9, Byte 0x000c: irmovl stack, %ebp //Set up base pointer
I've tried putting the .pos 0 line inside the init function (I thought it might help) as well as simply nixing the init: line all together but I still get the same problem.

Possible solution:
If you have the Stack label defined at the bottom of your file, try creating an extra blank line after it. I was literally just having the same issue and creating a blank line after the Stack label fixed the problem.
As an aside:
It's absolutely amazing that this is the only search result I've come across regarding this error.

Related

I am trying to write a simple MIPS program that will add hexadecimal numbers, but I keep getting an error

I a writing a simple MIPS code to add two hexadecimal values and store the results in a register. I am new to MIPS so I am having trouble finding the fix to an error message I have. Any help would be appreciated.
.text
.globl main
main: add $t2,$t0,$t1 # add contents of $t0 and $t1, and store result in $t2
li $v0,10 # terminate execution
syscall
the error message:
Error in C:\Users\smpan\OneDrive\Desktop\Computer\Computer Lab 2\Exercise4_3.asm line 4: Runtime exception at 0x00400000: arithmetic overflow
My goal for the program is to try and verify my hexadecimal addition is correct. I am adding 0x7FAA3278 and 0x6024CD12. The program should store the result 0xDFCEFF8A is the registered $t2.
Line 14 is the line that contains main:
The result of that addition is too big to fit in a signed 32 bit value, and the CPU is telling you exactly that.
If you're expecting an unsigned result, or are happy with a negative result from adding two positive numbers, there's an 'add unsigned' instruction.
See here:
Difference between add and addu

DW_OP_fbreg 'operand' to retrieve value of a variable is not working as expected?

Setup: I am debugging a simple C++ program compiled with option -fno-omit-frame-pointer, using libwarf for DWARF 5. Main work is to write a debugger using libdwarf.
For a particular local variable, dwarfdump shows:
DW_AT_location len 0x0002: 915c: DW_OP_fbreg -36
In the following I will refer to '-36' as 'op1', which I get from libdwarf.
Problem: Using op1 directly results in incorrect value for the variable.
(fbPointer is current value of frame base pointer).
int32_t data = (int32_t) ptrace(PTRACE_PEEKDATA, processPid, fbPointer + op1, 0);
I also tried decoding -36 as sleb128 and usleb128, and for both I got 220. Not a good value.
Trial/error shows that if I add 16 to op1, it will work for any number of int variables as parameters and local objects. However, it does not work for float/double.
Question: Is -36, as mentioned everywhere, offset of variable from frame-base pointer? If so, what am I doing wrong?
What are the preceding values in DW_AT_location: "len 0x0002: 915c:"? If they are important in evaluating op1, how do I get them via libdwart?
Thank you very much. It has been more than a week I am stuck at this point.
It seems that DW_OP_fbreg is a reference to DWARF register which in this case is 16 bytes off. That is, we need to add 16 to RBP, the real register, then add -36 to that. Finally, somehow in this case -36 is a plain number as opposed to encoded sleb128.

Linker error: "bad address <value> for zero page symbol <name>"!

I'm trying to make COSMIC compiler allocate a struct at a specific address in the memory (0x5420). I added the following lines in my C code (where CAN_TypeDef is a typedef struct):
#pragma section [mycan]
CAN_TypeDef CAN;
#pragma section []
In the IDE (STVD), I created a new section named Can inside which I created a new section named .mycan.
When I build the code in STVD, a linker error appears saying:
#error clnk Debug\can.lkf:1 bad address (0x5420) for zero page symbol _CAN
In the above picture, it is clear that Can and Zero Page are two different segments. What can be the cause of this error and how can I solve it?
I don't know the STM8, but I think I found it. In the STVD documentation I read:
Global variables
When the category is set to General , you can use
the Global Variables list box to specify the default location of
global variables:
In Zero Page: This is the default option.
In Data: Specifies to place global variables in the first 64Kbytes of
memory.
So the compiler assumes all global data sitting in the zero page and the addresses are just eight bit wide. Only the linker sees that the section .mycan is not in the zero page and you get an error. I would try #near CAN_TypeDef CAN; or simply extern CAN_TypeDef CAN #5420; without creating your own section.

How to Write GRUB stage1.S in NASM?

I am trying to write a multi stage boot loader using NASM and gcc.
For this purpose I am referring grub boot loader source.
I have written a stage1 loader, but stuck at over writing partition
tables of MBR.
In grub stage1.S, they are using code like this to skip partition tables:
. = _start + STAGE1_PARTEND
.word STAGE1_SIGNATURE
How can I do that in NASM?.
using times it will over write the partition tables.
So please help me.
Assigning a value to . is treated the same as a .org directive (see this page).
Thus, the code you pasted is changing the current origin to _start + STAGE1_PARTEND and placing a word with the value STAGE1_SIGNATURE there.
So in NASM code you should be able to do something like:
fill: times _start+STAGE1_PARTEND-$ db 0
dw STAGE1_SIGNATURE
; .word is 16 bits on x86 (regardless of .code16 / .code64)
Also see this example in the NASM manual showing how to pad a BIOS boot sector this way, as a replacement for MASM-style org or GAS-style . = new_position actually seeking and filling with padding in a flat binary output file.
times STAGE1_PARTEND-($-_start) db 0
dw STAGE1_SIGNATURE
Right, Nasm will accept only one "org" directive. The Nasm equivalent of "." is "$", but I don't think that'll help you either. I don't have the GRUB code on hand, or I'd look. Where does the partition table "come from"? If it's read from disk, there may be a signature already in place(?). Perhaps you can simply "stop" the Nasm code before overwriting the partition table and leave the existing sig in place? Nasm will do almost "anything you want", but this may be an exception. It won't "move" (skip) and assemble more at a new place as (G)as is apparently doing here - at least not readily. I may need to download the GRUB code to figure out a workaround. Possibly something like...
; stage1 code
; possible padding here?
%incbin "partition_table.bin"
dw (SIG) ; if not part of the .bin code?
... or something.

What does '__asm__(".previous");' mean?

While trying to compile my project, that uses some third party headers, with mingw 4.4, I encountered the following error:
Assembler messages:
Error: junk at end of line, first unrecognized character is '"'
Error: unknown pseudo-op: '.previous'
I found this code at the end of one of the included headers:
__asm__(".section \".plc\"");
__asm__(".previous");
Since I do not have any experience at all with in-line assembler instructions, I googled for an explanation to it, but couldn't find the answer to my two basic questions. What does __asm__(".previous"); acctually do and why would anyone put this at the end of a header file.
These are the only __asm__ instructions in the whole project. Can I safely delete them? Or is there a way to define .previous in order to make it a known pseudo-op?
Enlighten me, please!
.previous is a directive that lets you swap back and forth between two elf sections. It is a shortcut that allows denser assembly files and lets you for example declare initialized data within a stream of code or vice versa.
For example say you have an assembler file with a data and a code section.
If you want - in the middle of a function - declare a constant in the data segment you can use the .previous statement like this:
nop // some code
.previous // swaps current section (code) with previous section (data)
MyConstant:
.word 0x0001 // some data
.previous // swaps curent section (data) with previous section (code)
nop // more code
More information can be found in the reference manual:
http://sourceware.org/binutils/docs-2.19/as/Previous.html#Previous

Resources