LOW() HIGH() to use variable instead of value - 8051

I know this is how we use LOW() and HIGH() operators:
MOV P3,#LOW(-10)
But what if -10 is a variable or an input on one of the ports? This is what I need:
MOV P3,#LOW(P0)
Which does not work. The Edsim51 simulator says that a label is expected. But I don't think how I can use a label here, maybe it means a function label, I tried that, but as far as I know, we cannot return a value from a function, so I still don't know how to use a function label here.
MOV P3,#LOW(func)
func:
RET P0
Which is incorrect.
This is the only thing I could find on the internet, just a discussion about this issue: https://community.arm.com/developer/tools-software/tools/f/keil-forum/22073/how-to-use-low-or-high-in-a51
On the official documentations, I can't even find LOW() and HIGH() operators anywhere, which is weird to me: https://www.keil.com/support/man/docs/is51/is51_instructions.htm

You don't.
It doesn't make sense, how do you take the low byte or the high byte of something that is only one byte wide to begin with?
You're not finding them in the official instruction documentation because they aren't instructions. The CPU never sees them. They're just assembler shortcuts. MOV P3, #LOW(-10) is just another way of writing MOV P3, #246 that makes programmer intent clearer.

Related

x86 Entering Graphics Mode on Macs

I am try to enter graphics mode in assembly on my Mac for learning purposes mostly. I have seen how to do it on Windows based like...
mov ax, 13h
int 10h
However, since I am on a Mac, I cannot use 'int' calls. Instead I use 'syscall.' So next I looked through Apples system calls here in hopes of finding something but I didn't come across anything that seemed helpful. Lastly I tried what how I would think the Mac equivalent would be like but I was confused without system calls. So....
mov rax, 0x200000(number) ; The number would be the system call
syscall ; int equivalent
I don't know what the number there would be. This may not even be possible, and if that is the case please say so, otherwise if anyone has any ideas if I'm headed in the right direction or completely wrong direction, help is appreciated.

Assembly syntax to distinguish two forms of near jump

I'm assembling the same source with two different assemblers. I expect to get two identical results (modulo memory offsets, exact value of NOPs and such). Yet I've suddenly encountered the weirdest issue: there are two possible encodings of JZ:
74 cb
and
0F 84 cw/cd
The displacement, in my case, fits into one byte, and one assembler (a flavor of GAS, I think) emits the former while another (MASM) emits the latter. Since I perform some validation by matching outputs, this throws the validation off.
I have rather little control over the options of GAS, but I have complete control over MASM. Question - is there an option, a directive, or a specific command syntax to force one encoding over the other?
If all of the code, except for this one instruction is the exact same when assembled, this looks like a bug in MASM. These instructions resolve to:
74: jz rel8
0F 84: jz rel16/32
So, MASM is improperly using more space for that opcode than it should. You may be able to remedy this by using a more explicit form of the instruction in MASM, like
jz byte my_label
However, if your machine code is different at all, this may be the proper behavior of MASM. Ensure that the signed word/dword argument to jz rel16 would fit into a signed byte

Debugging a SHA-256 implementation

I've been working on a SHA-256 implementation using MASM32, and got some source done. However, I can't get it working correctly and have looked at it, rewrote bits of it, and copied some source into the inline Delphi ASM and got it running perfectly, yet my original ASM source has problems. Given that I'm not incredibly experienced with it, Would it be possible for someone to look at the source and tell me if they see something I'm missing? I already did a Delphi implementation and have it working perfectly, so I know it's not the algorithm itself at fault but the ASM code itself.
I was planning on optimizing tasks after I simply got it working. But bear in mind that I am still learning (self-taught), so if you see something I do that is on the stupid side in this source, I'd like to be able to learn, too. But my main concern is getting it working since I'm not seeing where the error(s) are.
(Removed the ASM code for space concerns, since I know the problem now)
Edit: I figured out what the problem was. Which leads into the next logical question since I don't know: Why did this code cause a problem?
Changing the following at the end of the SHA256Loop macro:
ADD h, ECX
ADD h, EBX ; h := t1 + t2;
To this:
ADD ECX, EBX ; h := t1 + t2;
MOV h, ECX
Fixed it. Why couldn't I do two ADD instructions to the memory and get the same result as the ADD to register and then a MOV to memory?
Your first example with two ADD instructions depends on the previous contents of h. The second example is independent of the previous contents of h. If the value of h is not guaranteed to be zero, then those two examples will behave differently.

How to use int3( VEH or SEH )

Know I want to replace function prologue with jmp to jump to my allocate zone(VirtualAllocateEx). But function prologue just have 3 bytes, and jmp have 5 bytes.
like this:
55 `push ebp`
8B EC `mov ebp, esp`
833D C4354200 02 `cmp dword ptr ds:[4235C4],2`
E9 AD00000000 `jmp` 00140000 // replace above three instructions
If I want to use jmp to cover function prologue, the third instruction after function prologue must be covered.
So know I want to use int3 to replace function prologue to to jump to my allocate zone or any address, how can I do it?
I try to use VEH or SEH to do so, but I can't figure out how to make it.
You need to write the original code (the one you quoted) on another memory location (just allocate something).
Write it while saving some space for the additional OpCodes (your custom new code).
It doesn't have to fit exactly as you're allowed to fill the unused bytes with NOP (0x90 if I'm not mistaken).
Now, jump to this code from the original code.
I've been doing this stuff when I was making game trainers years ago.. Works very well.
On thing to note: Your reWritten code should, at the end, jump back to the original place to continue the code flow.
Let me know if it's unclear.

(8051) Check if a single bit is set

I'm writing a program for a 8051 microcontroller. In the first part of the program I do some calculations and based on the result, I either light the LED or not (using CLR P1.7, where P1.7 is the port the LED is attached to in the microcontroller).
In the next part of the program I want to retrieve the bit, perhaps store it somewhere, and use it in a if-jump instruction like JB. How can I do that?
Also, I've seen the instruction MOV C, P1.7 in a code sample. What's the C here?
The C here is the 8051's carry flag - called that because it can be used to hold the "carry" when doing addition operations on multiple bytes.
It can also be used as a single-bit register - so (as here) where you want to move bits around, you can load it with a port value (such as P1.7) then store it somewhere else, for example:
MOV C, P1.7
MOV <bit-address>, C
Then later you can branch on it using:
JB <bit-address>, <label>
Some of the special function registers are also bit addressable. I believe its all the ones ending in 0 or 8. Don't have a reference in front of me but you can do something like setb r0.1. That way if you need the carry for something you dont have to worry about pushing it and using up space on your stack.

Resources