IF Condition on Assembly not working - if-statement

Hi guy's I have this code, on assembly using the assembler FASM (FlatAssembler)
;REQUEST THE VALUE (1 OR 2)
mov ah, 3Fh
mov bx, 0
mov cx, 1
mov dx, valor
int 21h
;THE NOT WORKING IF
cmp [size], '2'
jmp small
cmp [size], '1'
jmp e
;ONE OF THE LABELS TO WHERE THE IF MUST JUMP
small:
mov cx, 10
mov dx, 9
.....
;OTHER LABEL
e:
mov ah, 07h
int 21h
The program does not jump to the labels already tryed the cmp [size], 2 and subtracted 48 to get the decimal value but no luck
Any help?

Instead of just calling jump after cmp [size],'2' you should use je
cmp [size], '2'
je small
cmp [size], '1'
je e
The processor keeps track of the last operation using the flags.In case of cmp it subtract the first value from the second.Then it checks the zero flag to find whether the two values in this case [size] and '2' are equal or not.

Related

Conditional jumps in assembler always give same result [duplicate]

Basic question here,
I wrote the following block:
IDEAL
MODEL small
STACK 100h
DATASEG
Var1 db 4
Var2 db 2
CODESEG
start:
mov ax, #data
mov ds, ax
xor ax, ax
mov al, [Var1]
cmp al, [Var2]
jg Var1Greater
mov ax, 1
Var1Greater:
mov ax, 0
I'm new to assembly.
I wanted to create a code that compares [Var1] to [Var2].
IF(!) [Var1] is greater than [Var2], execute mov ax, 1. IF(1) anything else(equal or less) excecute, mov ax, 0.
How can this be done? the code I wrote executes both instructions if the condition is true.
Ah, Turbo Assembler "Ideal" mode; It has been a while since I last saw it. I love Ideal mode. It is so much better thought-out and it makes so much more sense than Microsoft Assembler's syntax.
Well, what is happening is that both instructions get executed.
First, mov ax, 0 gets executed, and then control falls through to the next statement, which is mov ax, 1, so what you are left with in ax is 1.
Labels in assembly language do not magically cause control to jump elsewhere. They do not cause the assembler to emit any instructions. They only exist so that you can indicate the target of another jump instruction.
So, what you need is:
...
cmp al, [Var2]
jg Var1Greater
mov ax, 0
jmp skip
Var1Greater:
mov ax, 1
skip:
also, it is good form when writing assembly language to use xor ax, ax instead of mov ax, 0.
You must jump over Var1Greater too to skip mov ax, 1 instruction. As alternative you may do it like:
mov ax, [Var1]
cmp ax, [Var2]
mov ax, 1
jg skip0
mov ax, 0
skip0:

Go back after jump

I have this code, I need check RCX register three times. I made a few lines of code (24-34 lines). In the first time (first jz), I move to true: label, but after I can't go back and check it the second time (28-30 lines). My program just finish everytime after the first jz. How can I go back and check it three time?
default REL
extern GetStdHandle
extern WriteFile
extern ExitProcess
section .data
true_msg db 'Yes', 0
true_msg_len equ $-true_msg
section .text
global _main
_main:
and rsp, -10h
sub rsp, 020h
mov rcx, -0Bh
call GetStdHandle
;jmp true
mov rcx, 2
cmp rcx, 2
jz true
mov rcx, 0
cmp rcx, 0
jz true
mov rcx, 1
cmp rcx, 0
jz true
;----------------
add rsp, 28h ; Restore Stack Pointer
;----------------
mov rcx, 0 ; RCX - first argument.
call ExitProcess
;----------------
xor rax, rax
ret
true:
mov rcx, rax
mov rdx, true_msg
mov r8, true_msg_len
xor r9, r9
push r9
sub rsp, 20h
call WriteFile
I want to get something like:
if(...){
...
}
if(...){
...
}
if(...){
...
}
I need every condition to be checked.
There is a missunderstanding on how to execute this. In a simple way:
if (test) {
//block1
}
if (test2) {
//block2
}
if(test3) {
//block3
}
(Pay attention on where those block1, block2 and block3 will appear in my next exemple)
Each if needs to test (the test into parenthesys) and then either go and execute the possibility it is true and the possibility it is not true.
So it would be something like this:
;first if, start by comparing:
mov rcx, 2
cmp rcx, 2
jnz false1 ;jumps for the false possibility of the first if
;here you type what will happen when the first if is executed (block1)
false1: ;here the first if is finnished, this label is the jump for not executing that first if
;then now you execute the second if:
;first compare:
mov rcx, 0
cmp rcx, 0
jnz false2 ;jumps for not executing the if block
;here is block2
false2:
;now here the last if, just like the last two:
mov rcx, 1
cmp rcx, 0
jnz false3
;here block3
false3:
;here is the rest of your code after those ifs
I changed the logic for jumping in false possibility instead of true (as you did) because in cases where there is no "else" block, it makes the code smaller than the way you did.

Assembly: loop through a sequence of characters and swap them

My assignment is to Implement a function in assembly that would do the following:
loop through a sequence of characters and swap them such that the end result is the original string in reverse ( 100 points )
Hint: collect the string from user as a C-string then pass it to the assembly function along with the number of characters entered by the user. To find out the number of characters use strlen() function.
i have written both c++ and assembly programs and it works fine for extent: for example if i input 12345 the out put is correctly shown as 54321 , but if go more than 5 characters : the out put starts to be incorrect: for example if i input 123456 the output is :653241. i will greatly appreciate anyone who can point where my mistake is:
.code
_reverse PROC
push ebp
mov ebp,esp ;stack pointer to ebp
mov ebx,[ebp+8] ; address of first array element
mov ecx,[ebp+12] ; the number of elemets in array
mov eax,ebx
mov ebp,0 ;move 0 to base pointer
mov edx,0 ; set data register to 0
mov edi,0
Setup:
mov esi , ecx
shr ecx,1
add ecx,edx
dec esi
reverse:
cmp ebp , ecx
je allDone
mov edx, eax
add eax , edi
add edx , esi
Swap:
mov bl, [edx]
mov bh, [eax]
mov [edx],bh
mov [eax],bl
inc edi
dec esi
cmp edi, esi
je allDone
inc ebp
jmp reverse
allDone:
pop ebp ; pop ebp out of stack
ret ; retunr the value of eax
_reverse ENDP
END
and here is my c++ code:
#include<iostream>
#include <string>
using namespace std;
extern"C"
char reverse(char*, int);
int main()
{
char str[64] = {NULL};
int lenght;
cout << " Please Enter the text you want to reverse:";
cin >> str;
lenght = strlen(str);
reverse(str, lenght);
cout << " the reversed of the input is: " << str << endl;
}
You didn't comment your code, so IDK what exactly you're trying to do, but it looks like you are manually doing the array indexing with MOV / ADD instead of using an addressing mode like [eax + edi].
However, it looks like you're modifying your original value and then using it in a way that would make sense if it was unmodified.
mov edx, eax ; EAX holds a pointer to the start of array, read every iter
add eax , edi ; modify the start of the array!!!
add edx , esi
Swap:
inc edi
dec esi
EAX grows by EDI every step, and EDI increases linearly. So EAX increases geometrically (integral(x * dx) = x^2).
Single-stepping this in a debugger should have found this easily.
BTW, the normal way to do this is to walk one pointer up, one pointer down, and fall out of the loop when they cross. Then you don't need a separate counter, just cmp / ja. (Don't check for JNE or JE, because they can cross each other without ever being equal.)
Overall you the right idea to start at both ends of the string and swap elements until you get to the middle. Implementation is horrible though.
mov ebp,0 ;move 0 to base pointer
This seems to be loop counter (comment is useless or even worse); I guess idea was to swap length/2 elements which is perfectly fine. HINT I'd just compare pointers/indexes and exit once they collide.
mov edx,0 ; set data register to 0
...
add ecx,edx
mov edx, eax
Useless and misleading.
mov edi,0
mov esi , ecx
dec esi
Looks like indexes to start/end of the string. OK. HINT I'd go with pointers to start/end of the string; but indexes work too
cmp ebp , ecx
je allDone
Exit if did length/2 iterations. OK.
mov edx, eax
add eax , edi
add edx , esi
eax and edx point to current symbols to be swapped. Almost OK but this clobbers eax! Each loop iteration after second will use wrong pointers! This is what caused your problem in the first place. This wouldn't have happened if you used pointers instead indexes, or if you'd used offset addressing [eax+edi]/[eax+esi]
...
Swap part is OK
cmp edi, esi
je allDone
Second exit condition, this time comparing for index collision! Generally one exit condition should be enough; several exit conditions usually either superfluous or hint at some flaw in the algorithm. Also equality comparison is not enough - indexes can go from edi<esi to edi>esi during single iteration.

Code executes condition wrong?

Basic question here,
I wrote the following block:
IDEAL
MODEL small
STACK 100h
DATASEG
Var1 db 4
Var2 db 2
CODESEG
start:
mov ax, #data
mov ds, ax
xor ax, ax
mov al, [Var1]
cmp al, [Var2]
jg Var1Greater
mov ax, 1
Var1Greater:
mov ax, 0
I'm new to assembly.
I wanted to create a code that compares [Var1] to [Var2].
IF(!) [Var1] is greater than [Var2], execute mov ax, 1. IF(1) anything else(equal or less) excecute, mov ax, 0.
How can this be done? the code I wrote executes both instructions if the condition is true.
Ah, Turbo Assembler "Ideal" mode; It has been a while since I last saw it. I love Ideal mode. It is so much better thought-out and it makes so much more sense than Microsoft Assembler's syntax.
Well, what is happening is that both instructions get executed.
First, mov ax, 0 gets executed, and then control falls through to the next statement, which is mov ax, 1, so what you are left with in ax is 1.
Labels in assembly language do not magically cause control to jump elsewhere. They do not cause the assembler to emit any instructions. They only exist so that you can indicate the target of another jump instruction.
So, what you need is:
...
cmp al, [Var2]
jg Var1Greater
mov ax, 0
jmp skip
Var1Greater:
mov ax, 1
skip:
also, it is good form when writing assembly language to use xor ax, ax instead of mov ax, 0.
You must jump over Var1Greater too to skip mov ax, 1 instruction. As alternative you may do it like:
mov ax, [Var1]
cmp ax, [Var2]
mov ax, 1
jg skip0
mov ax, 0
skip0:

Inline asm and c array questions

This is a homework. I have 3 arrays, v1={5,4,3,2,1} ,v2={1,2,3,4,5} and v3={2,3,5,1,4}, the assigment is to change the 1 to 6. Of course, any solution like v1[4]=6, in asm or c is forbidden. So this was my code:
First Code
void main(){
int myArray[5]={5,4,3,2,1};
__asm {
mov ecx,0 //using ecx as counter
myLoop:
mov eax, myArray[ecx] //moving the content on myArray in position ecx to eax
cmp eax,1 //comparing eax to 1
je is_one //if its equal jump to label is_one
inc ecx //ecx+1
cmp ecx,5 //since all vectors have size 5, comparing if ecx is equal to 5
jne myLoop //if not, repeat
jmp Done //if true, go to label Done
is_one:
mov myArray[ecx],6 //changing the content in myArray position ecx to 6
inc ecx //ecx+1
cmp ecx,5 // ecx=5?
jne myLoop //no? repeat loop
jmp Done //yes? Done
Done:
}
printArray(myArray);
}
this didn't work, tried many things like mov eax,6 or mov [eax+ecx],6 , nothing worked until I found this solution
Many tries later code
void main(){
int myArray[5]={5,4,3,2,1};
__asm {
mov ecx,0 //using ecx as counter
myLoop:
mov eax, myArray[TYPE myArray*ecx] //I don't understand how this works
cmp eax,1 //comparing eax to 1
je is_one //if its equal jump to label is_one
inc ecx //ecx+1
cmp ecx,5 //since all vectors have size 5, comparing if ecx is equal to 5
jne myLoop //if not, repeat
jmp Done //if true, go to label Done
is_one:
mov myArray[TYPE myArray*ecx],6 //Uhh...
inc ecx //ecx+1
cmp ecx,5 // ecx=5?
jne myLoop //no? repeat loop
jmp Done //yes? Done
Done:
}
printArray(myArray);
}
And that works like a charm. But I don't understand how or why the MOV array[TYPE array * index], value works(besides TYPE returning the size as explained in link), and why not the others.
Also, since I have to do this for 3 arrays, I tried to copy and paste all the code to changingArray(int myArray[]), declared the 3 arrays in the main, and passed them to changingArray, but now is not changing them. Im pretty sure that with vector you dont have to pass with &, I could be wrong. Still, I can't see why it doesn't change them. So...
Final Code
void changingArray(int myArray[]){
__asm {
mov ecx,0 //using ecx as counter
myLoop:
mov eax, myArray[TYPE myArray*ecx] //I don't understand how this works
cmp eax,1 //comparing eax to 1
je is_one //if its equal jump to label is_one
inc ecx //ecx+1
cmp ecx,5 //since all vectors have size 5, comparing if ecx is equal to 5
jne myLoop //if not, repeat
jmp Done //if true, go to label Done
is_one:
mov myArray[TYPE myArray*ecx],6 //Uhh...
inc ecx //ecx+1
cmp ecx,5 // ecx=5?
jne myLoop //no? repeat loop
jmp Done //yes? Done
Done:
}
printArray(myArray);
}
void main(){
//for some odd reason, they arent changing
int v1[5]={5,4,3,2,1};
int v2[5]={1,2,3,4,5};
int v3[5]={2,3,5,1,4};
changingArray(v1);
changingArray(v2);
changingArray(v3);
}
TL:DR section:
Homework of changing the number 1 to 6 in 3 arrays v1={5,4,3,2,1} ,v2={1,2,3,4,5} and v3={2,3,5,1,4}
1-I don't get why the first code doesn't work, but many tries later code works (the MOV array[TYPE array * index], value instruction).
2- Since I need to do this with 3 arrays, I put all the code in changingArray(int myArray[]), and in the main I declared my 3 arrays in main as shown in final code. While many tries code did change the array, this doesnt. Probably I just made a mistake in c and not asm, but I don't see it.
And sorry for bad english, is not my first language.
mov eax, myArray[TYPE myArray*ecx]
Here the address referred to is (base address of myArray) + sizeof(the type of elements of myArray) * ecx. In assembly language the indexing should be done in bytes.