Code executes condition wrong? - if-statement

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:

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.

IF Condition on Assembly not working

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.

What style assembly is this (intel, att...etc?) and how can I produce it?

I'm trying to produce assembly code like this (so that it works with nasm)
;hello.asm
[SECTION .text]
global _start
_start:
jmp short ender
starter:
xor eax, eax ;clean up the registers
xor ebx, ebx
xor edx, edx
xor ecx, ecx
mov al, 4 ;syscall write
mov bl, 1 ;stdout is 1
pop ecx ;get the address of the string from the stack
mov dl, 5 ;length of the string
int 0x80
xor eax, eax
mov al, 1 ;exit the shellcode
xor ebx,ebx
int 0x80
ender:
call starter ;put the address of the string on the stack
db 'hello'
First off, what assembly style is this and second, how can I produce it from a C file using a command similar to gcc -S code.c -o code.S -masm=intel
This is Intel style.
What's wrong with the commandline you wrote in the question?

Porting Assembly to C/C++?

I would like to have this x86 ASM code ported to C or C++, as I don't understand ASM =)
Searching Google it seams Relogix and IDA Pro can do it. But I don't suppose they are cheap, given I only have this one source.
Understanding the math or the algorithm how it works would be just as good, as I am going to use OpenGL anyway.
Are there other methods?
;
; a n d r o m e d a
;
; a 256b demo
; by insomniac/neon
;
code SEGMENT
ASSUME CS:code, DS:code
p386
LOCALS
ORG 100h
max = 4096
maxZ = 5000
b EQU byte ptr
Start: lea di,vars
mov ch,60
rep stosw
mov al,13h
int 10h
p al: mov al,cl
mov dx,3c8h
out dx,al
inc dx
cmp al,64
jb b64_1
mov al,63
b64_1: out dx,al
mov al,cl
shr al,1
out dx,al
out dx,al
loop pal
.main: push 8000h
pop ES
mov si,max
.loop: mov ax,Z[si]
cmp ax,maxZ-(maxZ/4)
jg NewStar
cmp ax,2
jg Zok
NewStar:
mov ax,bp
mov X[si],ax
imul ax,8405h
inc ax
mov bp,ax
shr ax,6
sub ax,400
mov Y[si],ax
mov Z[si],maxZ-(maxZ/2)
Zok: mov ax,X[si]
movsx dx,ah
shl ax,8
mov cx,Z[si]
idiv cx
add ax,320/2
cmp ax,320-1
jge NewStar
cmp ax,1
jle NewStar
mov di,ax
mov ax,Y[si]
movsx dx,ah
shl ax,8
idiv cx
add ax,200/2
imul ax,320
add di,ax
mov al,127
stosb
mov ax,X[si]
cmp ax,00
jge .add
neg ax
shr ax,6
add Y[si],ax
jmp .notadd
.add: shr ax,6
sub Y[si],ax
.notadd:
add Z[si],ax
mov ax,Y[si]
sar ax,3
add X[si],ax
.NextStar:
dec si
dec si
jnz .loop
push DS
push ES
pop DS
xor di,di
xor cx,cx
.blur: movzx ax,DS:[di]
movzx dx,DS:[di+1]
add ax,dx
mov dl,DS:[di-320]
add ax,dx
mov dl,DS:[di+321]
add ax,dx
shr ax,2
cmp al,0
je .skip
dec ax
.skip: stosb
loop .blur
push 0a000h
pop ES
mov si,di
mov ch,81h
rep movsw
pop DS
mov dx,3dah
.vrt: in al,dx
test al,8
jz .vrt
in al,60h
dec ax
jnz .main
endprog:
mov al,3
int 10h
ret
LABEL vars
X dw max DUP (?)
Y dw max DUP (?)
Z dw max DUP (?)
code ENDS
END Start
In general case, this cannot be done. In this particular case, this cannot be done because this assembly program interacts with PC BIOS directly, using int 10h to turn on 320x200 256 VGA mode, and it interacts with PC hardware directly, by writing to IO ports 0x3c8 and 0x3c9 (this sets the VGA palette) and by reading from 0x3da (VGA status register) and 0x60 (PC keyboard microcontroller). It also writes directly to VGA video memory.
Under the conditions of executing on a PC-compatible computer with MS-DOS or similar OS (or, within a simulated environment such as dosbox), this can be done: you can either make each CPU register a C variable and each assembly mnemonic a C function that modifies those variables or writes at absolute memory addresses or IO ports (with outb() and inb()), or, and I think this would be a much more interesting task, understand the math this demo does, and implement that in a portable manner.
Either way, I haven't heard of tools that could do this automatically. Existing tools might handle simple logic, but understanding a demo is never an easy task! What automatic program can tell that
imul ax,8405h
inc ax
should be replaced with ax = rand();?
You could throw it on RentaCoder and pay someone a few $ to write a C version by hand, including an annotation how it was done.
There are quite a few methods of doing so, for example this or this. ;-)