Flag setting for CF , PF , AF , ZF , SF in MOV AX , BX - x86-16

MOV AX , BX. What will be the flag settings.
So , what is the answer to this.

No flags will get modified by the MOV instruction.

Related

How do I check if my assembly 8086 program runs well

I want to put numbers from 0 - 9 to memory cells 400h to 409h.
So for example at 400h -> 0 (put 0) and at 401h -> 1 (put 1) ..... 409h (put 9).
This is my code so far: (I dont know if it works)
IDEAL
MODEL small
STACK 100h
DATASEG
;----------
;----------
CODESEG
start:
mov ax , #data
mov ds , ax
mov es, ax
;----------
mov si , 400h
mov cx , 10
mov al , 0
agian:
mov [si],al
inc si
inc al
loop agian
;--------
exit:
mov ax,4c00h
int 21h
END start
There's a very simple way to see if your program works. Just write the values in the video memory. That way you'll know if it works.
start:
mov ax, 0B800h ;NEW
mov ds, ax
mov es, ax
;----------
mov si, 400h
mov cx, 10
mov al, 48 ;NEW value 0 -> character 0
agian:
mov [si], al
add si, 2 ;NEW 1 character occupies 2 bytes in video memory
inc al
loop agian
mov ah,00h ;NEW wait for a keystroke so you can actually see
int 16h ;NEW ... the output
If you can invest the time you could learn to use the DOS utility DEBUG.EXE. Amongst other things it allows you to single step your program and view memory .
The easiest way to check if your ASM code is working the way you expect is to run it in a debugger. If you're running on Windows, OllyDbg 2 would be a good candidate — it will show you the current values of the registers, state of the stack, etc., so you can see how they change as you step through your code. You can modify the code from inside OllyDbg too.
You can write breakpoints in your code with the int 3 instruction, or use the debugger to place breakpoints at runtime.

Adding two numbers in base 10 on Assembler

How can I add 2 numbers that their value is on base 16 and make the result on "base 10" on assembler. For example:
"5h+5h=10h" - I know it's wrong, I just want it to be visually 10h
And not:
5h+5h=Ah
CODE:
MOV AX,5h
MOV BX,5h
ADD AX,BX
result: ax=Ah - Not the result that i want...
result: ax=10h - The result that i want.
I tried to figure it out with google but didn't find anything that can help me...
Here is the code you are looking for
MOV AX,5h
MOV BX,5h
ADD AX,BX
DAA
Now AX contains 10h
Ok so i figure it out with #Fifoernik 's help
so the problem is that if i want to do it with 16bit (for example 99h+1h) values i need to do it like this using DAA operan and CF flag
pop ax
pop bx
add al,bl
daa ; dec id values
mov cl,al
mov al,ah
jc Carry; do i have carry
add al,bh
daa ; do the magic thing
JMP finito
Carry:
add al,1 ; add the carring...
add al,bh
daa ;can some one tell me what exactly daa does?
finito:
mov ch,al
push cx
ret
daa working only on AL so you'ill need to use the carry flag to add the carry like:
AH AL
1 <----- carry
00 99 <-- DAA take care of the 99 and make it 0 when its A0h
00 01+
-- --
01 00 ---> result 100h

MASM, address 9ffffh

i have some strange things.
Here is example of code.
CODESEGMENT segment
assume CS: CODESEGMENT, DS: CODESEGMENT, SS: NOTHING, ES:NOTHING
org 100h
BEGIN: mov AX, 9fffh
mov DS, AX
mov CX, DS:000FH
;-----------------------------------------------------
;End of program, exit to DOS
;-----------------------------------------------------
mov AX, 4c00h
int 21h
CODESEGMENT ends
end BEGIN
and this code
CODESEGMENT segment
assume CS: CODESEGMENT, DS: CODESEGMENT, SS: NOTHING, ES:NOTHING
org 100h
BEGIN: mov AX, 9000h
mov DS, AX
mov BX, [0FFFFH]
;-----------------------------------------------------
;End of program, exit to DOS
;-----------------------------------------------------
mov AX, 4c00h
int 21h
CODESEGMENT ends
end BEGIN
I think that when i get offset from DS i have, for example this,
DS = 9000h
offset = FFFFh
DS = 9000h * 10h = 90000h
+
0FFFFh
=
9FFFFh
Thinking this way i wrote this two codes.
And i thought this codes did the same thing - reading to CX two bytes from address 9FFFFh, but i looked in masm debugger (afd) and understood that i was wrong.
First code:
Second code
I use masm because i'm student, and i get used to it.
Please can some tell me where is my mistake.

a program works in Turbo Debugger when I step through it, but when I run it in TD or DOS it stops and Ctrl+Alt+Delete becomes the only option

The program was meant to display char table using BIOS int 10h, and it does it but only when I step through it in td. I thought that maybe while in debugger uninitialized registers contain zero, but while running they can possibly contain trash, therefore I put mov ax, 0003h instead of mov al, 3 and added xor dx, dx; but it does not works either.
.model tiny
.code
org 100h
start:
mov ax, 0003h
int 10h
xor dx, dx
mov si, 256
mov ax, 0900h
mov cx, 1
xor bh, bh
mov bl, 00011111b
cloop:
int 10h
push ax
mov ah, 2
inc dl
int 10h
mov ax, 0920h
int 10h
mov ah, 2
inc dl
int 10h
pop ax
inc al
test al, 0Fh
jnz con_loop
mov ah, 2
inc dh
xor dl, dl
int 10h
pop ax
con_loop:
dec si
jnz cloop
ret
end start
You need an additional PUSH. You should never trust BIOS/DOS/others to preserve AX even if it is not an output register.
test al,0Fh
jnz con_loop
push ax ;You forgot this!!!
mov ah,2
inc dh
xor dl,dl
int 10h
pop ax
con_loop:
You've got a pop instruction that doesn't correspond to a push:
push ax
...
pop ax
inc al
...
int 10h
pop ax <-- HERE
con_loop:
That last pop should be removed.

Bootloader memory location

This is a part of a bootloader that I am studying from
`[ORG 0x00]
[BITS 16]
SECTION .text
jmp 0x07c0:START ; set CS(segment register) to 0x07C0 and jump to START label.
TOTALSECTORCOUNT:
dw 0x02
KERNEL32SECTORCOUNT:
dw 0x02
START:
mov ax, 0x07c0
mov ds, ax ; set DS(segment register) to the address of the bootloader.
mov ax, 0xb800
mov es, ax ; set ES(segment register) to the address of the video memory starting address.
; stack initialization
mov ax, 0x0000
mov ss, ax
mov sp, 0xfffe
mov bp, 0xfffe
; clear the screen
mov si, 0
CLEARSCREEN:
mov byte[es:si], 0
mov byte[es:si + 1], 0x0a
add si, 2
cmp si, 80 * 25 * 2
jl CLEARSCREEN
; print welcome message`
I don't understand the beginning: jmp 0x07C0:START How does it set the CS register?
And what are the two variables TOTALSECTORCOUNT and KERNEL32SECTORCOUNT for? They don't appear anywhere in the bootsector file and if I remove them, the bootloader fails to load the welcome message.
Removing the parts causes the OS to fail to load. So what is the significance of that jmp statement and the two variables?
``[ORG 0x00]
[BITS 16]
jmp START
START:
mov ax, 0x07c0
mov ds, ax ; set DS(segment register) to the address of the bootloader.
mov ax, 0xb800
mov es, ax ; set ES(segment register) to the address of the video memory starting address.
; stack initialization
mov ax, 0x0000
mov ss, ax
mov sp, 0xfffe
mov bp, 0xfffe
`
I am not great with assembly and usually use the AT&T syntax also. I have however written a bootloader before.
Hopefully you have learnt about the segmented addressing system used in 16 bit applications. The cs register holds the code segment. http://wiki.osdev.org/Segmentation
jmp 0x07C0:START ;This is a long jump
jmp segment:offset
A long jump sets the cs register to segment parameter and then does a jump to the offset parameter. When you do a short jump the cs register doesn't change. I assume that it would contain 0x0. You can use a short jump but you must tell your assembler or linker where the code will be run.
EDIT: After reading the code again there is the [org 0x00] line. This sets the cs register to 0x00 by default. If you wanted to use the short jump try changing this line to [org 0x7c00]
CS should already be set to 0x7c00 by the BIOS so the line:
jmp 0x07c0:START
can be replaced by:
jmp START
The two variables you mention must be use elsewhere in the code to load the kernel. However, it appears you haven't posted the whole code here.
Without seeing the rest of the bootsector code, we cannot help.

Resources