# Assembly

Страница 2/5
1 | | 3 | 4 | 5

So it still drives me insane. Somehow things simply do not tick as I expect. The example above I have abandoned. Now I have another "simple" try. Take a value, shift right, shift right, logical NOT on that value, shift left, shift left. Finish.

I found out that I can only load values from TP in register HL, each time I try to load something in A I can't send it back. Register A seems important because CPL (for the logical NOT) only works on register A. XOR also only seems to work on A but you get too choose the registers you can XOR with. So getting A working is important. However I can't get anything done with A. example:

```{ This procedure with 56 as a value has 56 as result }
Procedure plus(VAR nValue);
begin;
inline ( \$3A/nValue/  { ld a, (nValue) }
\$3C/                         { inc a }
\$32		              { ld (nValue),a }

);
end;
```

On too the part I wanted to achieve:

```procedure ssnss(var bChar);
begin;
inline(
\$06/\$FF/                 {ld b,255)
\$2A/bChar/		{ld HL,(bChar) }
\$CB/\$3E/		        {SRL HL}
\$CB/\$3E/                  {SRL HL  <- after two shifts I get 14 for my start value 56, that seems correct}
\$7c/			        {ld a,h. but HL is 16 bit and A is 8 so I need too choose. 56 fits in 1 byte (not sure if this works)}
\$A8/   		        {xor b. <- beyond this point I am lost}
\$67				{ld h,a}
);
{ The shift L operations on HL are simple, but I can't find a way to use register A so this goes nowhere..}
end;
```

So it seems I am only able to get stuff from TP in to the HL register.. I am sure I am doing something wrong but what..
Any suggestions are welcome.

LD (56), A won't work because 56 is in ROM and can't be changed.

LD H, A should probably be LD L, A though I'm not 100% sure what you mean.

Didn't turbo pascal have a convention to pass parameters to a fubction call and receive parameters back?
depending upon the quantity of parameters it may even use the stack.
I suggest you to disassemble some code generated by the compiler to check how the compiler passes the parameters and also check if the compiler saves the processor registers before calling the function because it might be necessary to save them inside your function.
Do you have the documentation for the compiler?

Thom wrote:

LD (56), A won't work because 56 is in ROM and can't be changed.

LD H, A should probably be LD L, A though I'm not 100% sure what you mean.

Arent you confusing \$3A (LD A,(**)) with \$3E (LD A,*)?
I am trying to get the lowest 8 bytes, from HL in A because that register can do XOR operations.

Danjovic wrote:

Didn't turbo pascal have a convention to pass parameters to a fubction call and receive parameters back?
depending upon the quantity of parameters it may even use the stack.
I suggest you to disassemble some code generated by the compiler to check how the compiler passes the parameters and also check if the compiler saves the processor registers before calling the function because it might be necessary to save them inside your function.
Do you have the documentation for the compiler?

Yes, I have the documentation with the compiler: no it does not go in to that much detail. As too the suggestion: reverse engineer the code the compiler produces is a step above my knowledge. I am trying to learn assembly. I can push a lot of stuff though. Thanks

Didn't turbo pascal have a convention to pass parameters to a fubction call and receive parameters back?
depending upon the quantity of parameters it may even use the stack.
I suggest you to disassemble some code generated by the compiler to check how the compiler passes the parameters and also check if the compiler saves the processor registers before calling the function because it might be necessary to save them inside your function.
Do you have the documentation for the compiler?

This is not about TP, it is about how do I correctly shift, shift, not, shift, shift in assembly. where my byte comes in, in register HL. I can inline the code in TP.

`srl hl` doesn’t exist. The rotate and shift instructions can only affect 8-bit registers.

The only single-instruction 16-bit shifts that exist are `add hl,hl`, `add ix,ix` and `add iy,iy` (act like a “sla hl/ix/iy”) and `adc hl,hl` (act like a “rl hl”).

If you want a right shift of `hl` you need to do it in two steps: `srl h` then `rr l`.

Furthermore it seems you want to complement the value. You load 255 in `b` and then `xor b`, however there are two better ways: 1. you can do `xor 255` directly, and 2. for this specific case there is the `cpl` instruction.

To complement the entirety of `hl`, simply temporarily load the components into `a` twice: `ld a,l`, `cpl`, `ld l,a`, `ld a,h`, `cpl`, `ld h,a`.

Alternatively, you could do a 16-bit subtraction from FFFFH: `ex de,hl`, `ld hl,0FFFFH`, `and a`, `sbc hl,de`. (The `and` clears the carry flag for the `sbc`.) It is up to you which you prefer.

Thats (multiple) answera I can work with. Thank you! SRL (HL) has opcode \$CB/\$3E or should I write that as \$CB3E? (see http://clrhome.org/table/#)

Thanks

I think you wrote the opcode correctly. But `srl (hl)` does not shift the `hl` register value, it shifts the 8-bit contents of the memory address that `hl` points to! Note that ( ) indicates indirection in Z80 assembly.

`ld hl,bChar` - load `hl` with the value bChar
`ld hl,(bChar)` - load `hl` with the two bytes at address bChar and bChar + 1

`srl hl` - does not exist, use `srl h`, `rr l`
`srl (hl)` - shift the contents of memory at address specified in `hl`

Страница 2/5
1 | | 3 | 4 | 5