If the Y pointer stores the address of the byte in memory it points to, how is the value stored at the location accessed?
.dseg ; Define a data segment
Cap_string: .byte 5
main:
ldi yl, low(Cap_string)
ldi yh, high(Cap_string)
The instruction to read from the location that a pointer is pointing to is called "Load Indirect" and looks like this:
ld r5, Y
In the example above, r5 can probably be any register, and Y is the name of the pointer, and can be replaced with X, Y, or Z.
To write to the location, use the "Store Indirect" instruction, which is written like this:
st r5, Y
You can find more information in the AVR Instruction Set Manual.
Related
I ve this code, there we have a distance (D) and an angle (A), the functions must returns X, x=cosine(a)*d and Y, y=sine(a)*d
.data
n180 word 180
d word 60
a word 10
x word 0
y word 0
.code
fild word ptr a
fild word ptr n180
fdiv
fldpi
fmul
fsincos
fild word ptr d
fmul
fistp word ptr x
fwait
fxch
fild word ptr d
fmul
fistp word ptr y
at first time i run the program (using a=10 and d=60) i get X=59 e Y=-32768
here X is right, i get it before use FXCH but Y is wrong. if i run the program again then i get X=59 and Y=10
now it's ok
Why first time I run I get an error with FXCH?
For completeness...
... the no-operand FADD, FDIV, FDIVR, FMUL, FSUB and FSUBR all pop the right-hand argument ST(0) (so the left-hand argument ST(1) is replaced by the result, and then the stack is popped and the result becomes ST(0)).
... so the FXCH is not required.
... indeed, without the FXCH your sequence of operations leaves the FPU register stack in the same state as it started in (assuming it does not overflow at any point), which is generally a Good Thing.
I note that both FADD and FADDP etc. (with no operands) are just shorthand for FADDP ST(1), ST(0) (Intel ordering) and that is not the same as FADD ST(1), ST(0). I note also that the Intel manual prefers the FADDP etc. mnemonics for the no-operand form.
I am having a difficult time understanding this particular problem. I have the answers, but I really want to know the reason as to why they are what they are! I understand how each opcode works, just not in applying it to this problem.....
An engineer is in the process of debugging a program she has written. She is looking at the following segment of the program, and decides to place a breakpoint in memory at location 0xA404. Starting with the PC = 0xA400, she initializes all the registers to zero and runs the program until the breakpoint is encountered.
Code Segment:
0xA400 THIS1 LEA R0, THIS1
0xA401 THIS2 LD R1, THIS2
0xA402 THIS3 LDI R2, THIS5
0xA403 THIS4 LDR R3, R0, #2
0xA404 THIS5 .FILL xA400
Show the contents of the register file (in hexadecimal) when the breakpoint is encountered.
Again, I'm not seeking a list of answers, but an explanation to help me understand what exactly is going on in the program. Thanks so much!
If the engineer put the breakpoint on line 0xa404 (stopping the program before 0xa404 is run), the code would do the following:
0xA400 THIS1 LEA R0, THIS1 ; LEA loads the address of THIS1 into R0.
; Since THIS1 is at memory location 0xA400,
; after this instruction R0 = 0xA400
0xA401 THIS2 LD R1, THIS2 ; LD loads the contents of the memory at
; THIS2 into R1. Since THIS2 is this very
; line its contents are this instruction,
; which is 0010001111111111 in binary or
; 0x23ff in hex, so after this line executes
; R1 hold 0x23ff
0xA402 THIS3 LDI R2, THIS5 ; LDI visits THIS5 and treats its value as a
; new memory location to visit. It visits
; that second location and stores its
; contents into R2. In this case, it would
; look at THIS5 and see its value is 0xA400.
; It would then visit 0xA400 and store its
; contents in R2. 0xA400 contains the first
; line of your program which translates to
; 1110000111111111 in binary, 0xe1ff in
; hex, so it stores 0xe1ff into R2.
0xA403 THIS4 LDR R3, R0, #2 ; LDR starts from the memory location of R0,
; adds 2 to that, then stores whatever it
; finds in that memory location into R3. In
; this case R0 = 0xA400. It adds 2, bringing
; it up to 0xA402, which is the instruction
; immediately above this one. In binary, that
; instruction is 1010 0100 0000 0001, which
; translates into 0xa401 so the program stores
; the program stores 0xa401 into R3.
0xA404 THIS5 .FILL xA400
I've just tried to write my first program in assembly for x86 and I don't know why, but it doesn't make what I want. There's no errors, no communicates but the program doesn't open after pushing 'execute'. i want these program to add two variables and send back theirs sum. here's code:
.386
.model flat, stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
a dw 1h
b dw 2h
z dw 01 dup(?),0
.data?
.code
start:
mov ds, ax
mov ax, a
mov bx, b
clc
add ax, bx
mov edi, offset z
mov [edi], ax
mov ah, 09h
mov dx, z
int 21h
mov ah, 4ch
int 21h
end start
Please, help me :C
DOS function 09h expects a string; specifically, an array of bytes, each containing the ASCII code of a character, terminated by 24h (the ASCII code of $). Example:
z db '3$'
which is equivalent with:
z db 33h, 24h
Instead, you have defined z as an array of words, and fill the first word with 03h (the result of 1+2). In ASCII, 03h is a non-printing character.
Assembly is not some high-level language with convenient automatic type conversions. In assembly, you will have to convert the numeric value into a sequence of ASCII characters yourself.
How to do this? That has been asked numerous times already. Like here: Assembly, printing ascii number
Unless of course you have a convenient library with conversion functions lying around.
I am trying to simulate some simple asm code using Prolog. (32 bit)
I am new in Prolog and I am stucked in some problems without any solutions.
Basically if here is the code:
...
add eax, 1
...
and I want to simulate in this way:
...
EAX is EAX - 1,
...
and swipl will generate errors like :
Call: (7) 1 is 1-1 ? creep
Fail: (7) 1 is 1-1 ? creep
....
false
I know basically I could do like this:
EAX_temp is EAX + 1
But how can I keep manipulate EAX in next instructions..?
Could any one give me some help..? Thank you!
The "Prolog" way would be to actually maintain the state of all your registers in a term which you pass along the main predicate that runs the simulation. So, for example:
% general-purpose registers
% regs(EAX, EBX, ECX, EDX, ESI, EDI)
regs(0, 0, 0, 0, 0, 0)
But please note: this is not a predicate (hence the missing dot at the end)! This is a term, and it will be initialized to all zeros (I am assuming here):
init_regs(regs(0,0,0,0,0,0)).
So at the beginning of your program you can initialize your registers with:
main :-
init_regs(Regs),
step(Regs).
step(Regs) :-
read_instruction(Instruction),
apply_instruction(Instruction, Regs, New_regs),
step(New_regs).
apply_instruction(add(eax, Addend),
regs(EAX, EBX, ECX, EDX, ESI, EDI),
regs(New_EAX, EBX, ECX, EDX, ESI, EDI)) :-
New_EAX is EAX + Addend.
You can leave it at this, or you can have a helper predicate that provides access to the one register you need, for example:
reg_eax(reg(EAX, _, _, _, _, _), EAX).
reg_ebx(reg(_, EBX, _, _, _, _), EBX).
% and so on
And to set a register:
set_reg_eax(reg(EAX, EBX, ECX, EDX, ESI, EDI),
New_EAX,
reg(New_EAX, EBX, ECX, EDX, ESI, EDI)).
% and so on
which you can then use like this to define your apply_instruction/3:
apply_instruction(add(eax, Addend), Regs, New_regs) :-
reg_eax(Regs, EAX),
New_EAX is EAX + Addend,
set_reg_eax(Regs, New_EAX, New_regs).
The sort of predicates, reg_eax and set_reg_eax can be automatically generated by a library, library(record) (see here), with the initial idea proposed by Richard o'Keefe in his book "The Craft of Prolog" for doing exaclty this sort of stuff. If you use the libary, you don't need to write all the access and set predicates yourself.
If you are using SWI-Prolog, however, you can also make use of Dicts; see here. This is part of the current development version of SWI-Prolog (version 7) and makes dealing with structures with named arguments much easier.
There are probably several good ways to do this. And the answer might further be refined by your context which is currently not clear.
One way, is you could create dynamic facts for register values:
:- dynamic(register/2). % Fill in as needed
register(eax, 0).
register(ebx, 0).
...
add(Reg, Value) :-
( retract(register(Reg, OldValue))
-> NewValue is OldValue + Value
; NewValue = Value % If the register wasn't defined
),
assertz(register(Reg, NewValue)).
Then do:
add(eax, 4). % add eax,4
To read a register, you would just use, for example:
register(eax, EAXValue).
The main drawback of assert and retract is that they take a lot more CPU time than list manipulation. But I think they make sense for this kind of application where you have a CPU "state" that is represented by several register values.
I am building a CPU circuit with Logisim. My CPU has only 2 general purpose registers and a 16-byte RAM. I have encoded the following instruction set (Rxy means one of the two registers)
• ADD Rxy, Rxy (add Rxy and Rxy and store result inside the first register)
• SUB Rxy, Rxy (same but with sub)
• ST Rxy, Address (save value of Rxy into RAM address)
• LD Rxy, Address (load into Rxy value at RAM address)
• BZ Rxy, Address (branch to address if value of Rxy is zero)
I thought I could use decrement the second addend until it reaches 0 and at each step, add the first addend to itself.
For example, 5*3 = 5+5+5 ; 3-1-1-1
But I'm not sure my instruction can permit this program... I only have a branch if Rxy is equal to 0, whereas I would like to branch if not equal to 0.
My program currently looks like this :
Assume R1 is preloaded with second addends (iteration left count)
(A) LD R0, Address # constant 1
SUB R1, R0 # decrement iteration left
ST R1, Address # save iteration count in memory
LD R0, Address # Load first addend
LD R1, Address # load current total
ADD R0, R1 # do addition
ST R0, Address # save new current total
BZ R1, (B) # if iteration is 0, then display and end, else add
(B)
STOP
Is there a way to loop with my instruction set?
You can change
BZ R1, (B)
(B)
to
BZ R1, (B)
LD R0, Address # constant 1
SUB R0, R0
BZ R0, (A)
(B)