How does overflow work in ia-32?
For instance, what would happen to the following code? What flags would it throw?
movl $0x1, %eax
addl $7fffffff, %eax
Thanks!
If memory serves, addition sets the overflow flag is set when the sign bit changes without the carry bit being set. 1 + 0x7FFFFFFF would set overflow, clear carry, and clear zero.
Related
Take for example the result of multiplication of two 16 bit numbers. How will the parity flag be affected in the 8086 microprocessor and on what basis?Do we consider the entire 32 bit result or just the lower 8 bits?
If it's set according to the result, it's from the low 8 bits. e.g. add ax, bx sets PF according to AL.
Not all instructions do that, though. Consult the manual. For example mul https://www.felixcloutier.com/x86/mul leaves PF undefined.
BTW, your question title doesn't match your question at all. To check PF, you'd use an instruction like jp or jnp
Or lahf / and ah, 1<<2 to store FLAGS into AH and then AND to isolate the PF bit. https://en.wikipedia.org/wiki/FLAGS_register
Or on later CPUs, setp al or cmovp eax, edx would also be options.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
My question WAS about getting as much info as I could about registers...No luck :/
Everyone got everything so wrong [Probably because English is not my native language].
So, the question will be more general... ;(
I need a tutorial with the BASICS!
Ah...Could I be more not-specific?
Also, thanks for the help in advance!
In general you can use any of eax, ebx, ecx, edx, esi and edi pretty much as you want. They can each hold any 32-bit value.
Keep in mind that if you call any Win32 API functions that they are free to modify eax, ecx and edx. So if you need to preserve the values of those registers across a function call you'll have to save them somewhere temporarily (e.g. on the stack).
Similarly, if you write a function that is to be called by another function (e.g. a Windows callback) you should preserve ebx, esi,edi and ebp within that function.
Some instructions are hardcoded to use certain registers. For example, the loop instruction uses (e)cx, the string instructions use esi/edi, the div instruction uses eax/edx, etc. You can find all such cases by going through the descriptions for all the instructions in Intel's manual.
The "fixed uses" of the registers derive from the ancient roots back in the 8086 days (and in some ways, even from before that).
The 8086 was an accumulator machine, you were supposed to do math mostly with ax (there was no eax yet), and a bit with dx. You can see this back in many instructions, for example most ALU ops have a smaller form for op ax, imm (also op al, imm) than for op other, imm, and the ancient decimal math instructions (daa and friends) operate only on al. There are instructions that always reference (e)ax and maybe (e)dx as "high half", see the "old multiplication" (with the single explicit operand), imul with an immediate was added in the 80186, imul reg, r/m was added in the 80386 which added a whole lot of stuff including 32bit mode. With 32bit mode also came the modern ModRM/SIB structure, here are the old 16bit version and the modern 32/64bit version. In the old version, there are only 4 registers that could ever be used in a memory operand, so there's a bit of the "fixed roles for registers" again. 32bit mode mostly removed that, except that esp can never be the index register (that wouldn't normally make sense anyway).
More recently, Haswell introduced shlx which removes the restriction that shifting by a variable amount could only be done using cl as the count, and mulx partially removed the fixed roles of registers for "wide multiplication" (80186 and 80386 only added the "general" forms for multiplication without the high half), mulx still gives edx a fixed role though.
More strangely, the relatively recently added pblendvb assigned a fixed role to xmm0, previous to that the vector registers weren't encumbered by such old-fashioned restrictions. That fixed role disappeared with AVX though, which allowed the extra operand to be encoded. pcmpistri and friends still assign a fixed role to ecx though.
With x64 came a change to 8 bit register operands, if a REX prefix is present it is now possible to use spl, bpl, sil and dil, previously unencodable, but at the cost of being able to address ah, ch, dh or bh. That's probably a symptom of moving away from special roles too, since previously it wouldn't have made much sense to be able to use bpl, but now that it's "more general purpose" it might have some uses (it's still often used as a base pointer though).
The general pattern is towards fewer restrictions/fixed roles. But much of the history of x86 is still visible today.
As a general comment, before you go much further, I recommend adopting a programming style, or you'll find it very hard to follow your own code. Below is a formatted example of your code, maybe not everything is correctly formatted but it gives you an idea. Once in the habit, it's easier than making higgledy-piggledy code. One of its main advantages, is with practice you can cast your eye down the code and follow it far quicker than if you have to read every line.
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
ProgramText db "Hello World!", 0
BadText db "Error: Sum is incorrect value", 0
GoodText db "Excellent! Sum is 6", 0
Sum sdword 0
.code
start:
; eax
mov ecx, 6 ; set the counter to 6 ?
xor eax, eax ; set eax to 0
_label:
add eax, ecx ; add the numbers ?
dec ecx ; from 0 to 6 ?
jnz _label ; 21
mov edx, 7 ; 21
mul edx ; multiply by 7 147
push eax ; pushes eax into the stack
pop Sum ; pops eax and places it in Sum
cmp Sum, 147 ; compares Sum to 147
jz _good ; if they are equal, go to _good
_bad:
invoke StdOut, addr BadText
jmp _quit
_good:
invoke StdOut, addr GoodText
_quit:
invoke ExitProcess, 0
end start
I'll single out one line:
push eax ; pushes eax into the stack
Don't use comments to explain what an instruction does: use them to say what you are trying to acheive, or what the register represents, to give added value to the code.
Good luck to you: plenty of practice and midnight oil!
I'm pretty new to 8051 and was testing it out. After CJNE executes, it sets PSW to 0x80. Why does it do that? Below is the code. I am using the EdSim51DI simulator.
Any help would greatly be appreciated
The PSW is set to 0x80 because your first operand to the CJNE instruction is less than the second operand. Read on to better understand why.
The Program Status Word (PSW) contains status bits that reflect the current CPU state. The most significant bit (bit 7) in the PSW is the carry bit (C).
Operation: CJNE
Function: Compare and Jump If Not Equal
Syntax: CJNE operand1,operand2,reladdr
The CJNE instruction compares the value of operand1 and operand2 and branches to the indicated relative address if they are not equal. If the two operands are equal, program flow continues with the instruction following the CJNE instruction. This instruction also affects the carry flag in the PSW. The carry bit (C) is set if operand1 is less than operand2, otherwise it is cleared. This functionality allows you to use the CJNE instruction to perform a greater than/less than test for decision making purposes as demonstrated in the example below.
; The following code sample checks if the value in A is equal to, less
; than, or greater than 0x55. The NOP instructions can be replaced
; with code to handle each condition as desired.
CJNE A, #55h, CHK_LESS ; If A is not 0x55, check
LJMP EQUAL ; A is 0x55, so jump to EQUAL code
CHK_LESS: JC IS_LESS ; If carry is set, A is less than 0x55
IS_GREATER: NOP ; A is greater than 0x55
LJMP DONE
IS_LESS: NOP ; A is less than 0x55
LJMP DONE
EQUAL: NOP ; A is equal to 0x55
DONE: NOP ; Done with the comparison
I am looking at some assembly that was generated by disassembling some C programs and I am confused by a single optimization that I see repeated frequently.
When I have no optimizations on the GCC compiler uses the subl instruction for subtraction, but when I do have optimizations turned on (-O3 to be precise) the compiler uses a leal instruction instead of subtraction, example below:
without optimizations:
83 e8 01 subl $0x1, %eax
with optimizations
8d 6f ff leal -0x1(%edi), %ebp
Both of these instructions are 3 bytes long, so I am not seeing an optimization here. Could someone help me out and try to explain the compiler's choice ?
Any help would be appreciated.
It's hard to tell without seeing the original C code that produces this.
But if I had to guess, it's because the leal allows the subtraction to be done out-of-place without destroying the source register.
This can save an extra register move.
The first example:
83 e8 01 subl $0x1, %eax
overwrites %eax thereby destroying the original value.
The second example :
8d 6f ff leal -0x1(%edi), %ebp
stores %edi - 1 into %ebp. %edi is preserved for future use.
Keep in mind also that lea does not affect the flags whereas sub does. So if the ensuing instructions do not depend on the flags being updated by the subtraction then not updating the flags will be more efficient as well.
If I recall correctly, tail recursive functions always have an easy non-recursive equivalent.
Since recursion involves unnecessary function call overhead, it's better to do it the non-recursive way.
Is this assumption always true? Are there any other arguments for/against tail-recursion?
If you are using a language with a good compiler then these types of recursion can be optimised away, so in those cases if it improves readability to use recursion, I'd say to stick with it.
No, it's not always true. Many languages and/or compilers can easily optimize a tail recursive call , and rewrite it to an iterative version, or in some way reuse the stack frame for subsequent calls.
The Scheme language mandates that implementation employ tail call optimization
gcc can optimize tail calls as well, consider a function for freeing all the nodes in a linked list:
void free_all(struct node *n)
{
if(n != NULL) {
struct node *next = n->next;
free(n);
free_all(next);
}
}
compiles to, with optimization:
free_all:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
movl 8(%ebp), %eax
testl %eax, %eax
je .L4
.p2align 4,,7
.p2align 3
.L5:
movl 4(%eax), %ebx
movl %eax, (%esp)
call free
testl %ebx, %ebx
movl %ebx, %eax
jne .L5
.L4:
addl $20, %esp
popl %ebx
popl %ebp
ret
That is, a simple jump instead of recursivly calling free_all
No.
Go for readability. Many computations are better expressed as recursive (tail or otherwise) functions. The only other reason to avoid them would be if your compiler does not do tail call optimizations and you expect you might blow the call stack.
It depends on language, but often the overhead isn't that big. It may be subjective, but recursive functions tend be much easier to comprehend. Most of the time you wouldn't notice the performance difference.
I would go for tail recursion unless my platform was very bad at dealing with it (i.e. not doing it at all, but always pushing onto stack).