I'm trying to learn Y86, so I made a very simple program. It has an array of three long integers, and each block is filled by asking the user for an input through rdint
.
The compiled(?) program asks for three inputs, but is not able to print them out.
Code:
Main: irmovl Array, %edx
rdint %eax
rmmovl %eax, 0(%edx)
rdint %eax
rmmovl %eax, 4(%edx)
rdint %eax
rmmovl %eax, 8(%edx)
irmovl $10, %edi
Print: irmovl Array, %edx
mrmovl 0(%edx), %eax
wrch %eax
wrch %edi
mrmovl 4(%edx), %eax
wrch %eax
wrch %edi
mrmovl 8(%edx), %eax
wrch %eax
wrch %edi
halt
.align 4
Array:
.long 0
.long 0
.long 0
My input:
0
1
2
Output:
(three blank lines below)
Stopped in 22 steps at PC = 0x47. Exception 'HLT', CC Z=1 S=0 O=0
Changes to registers:
%edx: 0x00000000 0x0000004c
%edi: 0x00000000 0x0000000a
Changes to memory:
0x0004: 0x024008f2 0x00000001
0x0008: 0x00000000 0x00000002
Changes to memory: 0x0004: 0x024008f2 0x00000001 0x0008:
0x00000000 0x00000002
There is a classic problem with the program: Lack of new-line in the ys file, causing YAS to misbehave.
The first problem is due to an error in YAS. If you look in the yo file produced by YAS you will see that the last .long 0 statement never gets defined. You will probably also see that the first line opcode in the yo file is 0x00, i.e. nop (when YAS encounter a final instruction without an associated newline, it wraps it around, screwing up the yo file)
This means that you loose the first irmovl Array, %edx (it becomes some sort of nonsense, probably 0x00000000, i.e. 4 nops,) and so you write the first read character x'30' (ascii for '0') to the location pointd to by edx (which is probably 0x00000000,) is in the first instruction (which was 4 nops -- remember that you read a character, but it ends up in a 4 byte register and is saved as such.) So you are writing 0x00000000 to and address that was 0x00000000, which to YIS means that the register was not changed and therefore it is not shown in the "Changes to Memory" dump section.
You repeat this with the second read, writing 0x00000001 in the second word (overwriting the instruction in that location,) and with the third read, writing 0x00000002 in the third word (overwriting the instruction in that location.)
Now, of course, you are completely hosed! You reset the pointer to the array (using edx,) and attempt to print the content, but Array(0), Array(4), and Array(8) contains 0x00000000, because that is what you defined it as (using your .long 4 statements for Array(0) and Array(4) and automatically for Array(8) since the default set-up for undefined memory in Y86 is 0x00000000. And so, the program prints x'00' (because you print one character from a 4 byte word,) which, of course, is junk.
You will note that this fits with the dump from YIS. eax does not show as it is unchanged from 0x00000000, its initial value. edx and edi look A-OK, with edi pointing to Array(8). The only memory that has changed is the second and third word of the program (which have been overwritten with 0x00000001 and 0x00000002, respectively)
So, in summary. YAS makes a mistake. You must overcome this problem by adding a new-line after the last .long 0 statement. YIS misleads you because, critically!, it does not throw exceptions when you overwrite code with data.