This question already has answers here:
What does "int 0x80" mean in assembly code?
(9 answers)
Assembly (x86): <label> db 'string',0 does not get executed unless there's a jump instruction
(2 answers)
How to represent octal numbers in Assembly?
(2 answers)
How to make the kernel for my bootloader?
(1 answer)
Closed 3 months ago.
I am trying to get my C program to run on a computer with no operating system. I have a version of an MBR that just prints a (!), but when i try to add code to run my C program, as shown here the machine just reboots infinitely.
I only just got the assembly to compile because i took out some definitions and just put the numbers where it says //here
Here is my code:
`
[org 0x7c00]
mov [BOOT_DISK], dl
CODE_SEG equ GDT_code - GDT_start
DATA_SEG equ GDT_data - GDT_start
cli
lgdt [GDT_descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp CODE_SEG:start_protected_mode
jmp $
GDT_start:
GDT_null:
dd 0x0
dd 0x0
GDT_code:
dw 0xffff
dw 0x0
db 0x0
db 0b10011010
db 0b11001111
db 0x0
GDT_data:
dw 0xffff
dw 0x0
db 0x0
db 0b10010010
db 0b11001111
db 0x0
GDT_end:
GDT_descriptor:
dw GDT_end - GDT_start - 1
dd GDT_start
[bits 32]
start_protected_mode:
mov al, '!'
mov ah, 0x0f
mov [0xb8000], ax
;open the file for reading
mov eax, 5
file_name db 'e.exe'
mov ebx, file_name
mov ecx, 0 ;for read only access
mov edx, 0777 ;read, write and execute by all
int 0x80
;read from file
mov eax, 3
mov ebx, 1 //here
mov ecx, 26 //here
mov edx, 26 //here
int 0x80
jmp $
BOOT_DISK: db 0
times 510-($-$$) db 0
dw 0xaa55
`
Related
this image showcase the error im getting when running the command "bochs" in the bootDIr directory where my assembly file , the image ,the binary and the script are at , the tutorial i watched was using ubuntu while im using kali,i dont think that was relevant but i would love your help
the goal is to show the "Hello" String when booting (+some messages generated by the emulator)
here is the nasm code:
[BITS 16]
[ORG 0x7c00]
start :
xor ax,ax
mov ds,ax
mov es,ax
mov ss, ax
mov sp, 0x7c00
PrintMessage :
mov ah,0x13
mov al, 1
mov bx,0xa
xor dx,dx
mov bp, Message
mov cx, MessageLen
int 0x10
End :
hlt
jmp End
Message : db "Hello"
MessageLen : equ $-Message
times (0x1be -($-$$)) db 0
db 80h
db 0,2,0
db 0f0h
db 0ffh,0ffh,0ffh
dd 1
dd (20*16*63 - 1 )
times (16*3) db 0
db 0x55
db 0xaa
iam trying to write an assembly code 8086 i have two array X AND Y size 10 and i want to enter a number and check if its positive y will be 1 if negative it will be 0
but my code just displayed what i enter a number but i want it like this example .
example:
X : 2 -5 -7 8 -4 9 11 -12 90 -50
Y : 1 0 0 1 1 0 1 1 0 1 0
I wrote:
.MODEL SMALL
.DATA
x db 10 dup ("?")
y db 10 dup ("?")
.CODE
MOV AH,1
INT 21H
mov si,offset x
mov di,offset y
mov [si],al
cmp si,0
ja l1
jmp l2
l1 : mov al , 1
mov [di],al
jmp l3
l2 : mov ah , 0
mov y[di] , al
jmp l3
l3 :
MOV AH, 2
mov dl,al
INT 21H
cmp si,10
je l4
inc si
inc di
l4 :
.EXIT
END
The list of problems is long. Check out these comments and try to see why the error exists.
<<<< add label for a 10-time repeat
MOV AH,1
INT 21H
mov si,offset x <<<< move higher up for 1-time execution
mov di,offset y <<<< move higher up for 1-time execution
mov [si],al
cmp si,0 <<<< the byte to compare is in AL
ja l1 <<<< requires a SIGNED conditional, use JGE
jmp l2 <<<< reverse condition and drop this jump
l1 : mov al , 1
mov [di],al
jmp l3
l2 : mov ah , 0 <<<< should be AL
mov y[di] , al <<<< DI already refers to the y-array, use just [DI]
jmp l3 <<<< redundant
l3 :
MOV AH, 2
mov dl,al
INT 21H
cmp si,10 <<<< 10 is wrong
je l4
inc si <<<< move above checking iterator
inc di <<<< move above checking iterator
<<<< needs jumping back in order to repeat
l4 :
Next code, just like yours, inputs a single character from the keyboard and treats its ASCII code as the byte you want to store in the x array. For negative bytes you should input extended ASCII's. Use the Alt followed by a number up to 255.
.CODE
xor bx, bx
again:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
mov x[bx], al
mov ah, 255
shl ax, 1
not ah
mov y[bx], ah ; 1 for positive, 0 for negative
inc bx
cmp bx, 10
jb again
.EXIT
I am trying for hours and hours to access an array in assembly x86 TASM using dosbox - but I always get 'Operand types do not match' or 'Pointer expression needs brackets' error - I've searched the whole internet and couldn't find something that works in TASM x86.. this is the code:
IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
A DB 1, 2, 3, 4, 5, 6, 7, 8, 10, 11
; --------------------------
CODESEG
start:
mov ax, #data
mov ds, ax
; --------------------------
mov al,A[0]
; --------------------------
exit:
mov ax, 4c00h
int 21h
END start
Changing the line to:
mov ax, BYTE PTR A[0]
or to:
mov ax, A[BYTE PTR 0]
And even changing ax or al with all these combinations is failing.. or trying to acces the OFFSET of array A:
mov al, A[OFFSET A]
I don't know where's the problem..
Thank you for helping!
I was going to post this on codereview.stackexchange.com but the problem is this code does not work correctly.
I have an AT89C4051 processor which only has one hardware UART, however I will attach two UART-based devices to it of which one is my computer. The configuration across all devices is 9600,N,8,1 (9600bps, no parity, 8 data bits, 1 stop bit)
I attempted to create two software-based UARTs with machine-optimized code that can interface between the two devices, however the data I received on my computer is incorrect.
I was expecting 'ABCD' or 'abcd' to appear on the screen but all I received was 'DDDD'.
What can I do here to fix this problem without resorting to buying extra hardware?
;dual 9600bps channels
;RX1,TX1 = uart channel
;RX2,TX2 = uart channel
;start with uart configuration
org 0000h
ljmp uartcfg
;every 1/2 bit time execute function
org 000Bh
sjmp swuartint
SWCFG equ 20h ;serial config
;config for uart 1
SWRI bit 20h.0 ;data fully received if SWRI set
serrxslow bit 20h.2 ;bit flip-flop for receive. cpl 2x = 1 full bit time
SWTI bit 20h.1 ;data fully transmitted if SWTI set
sertxslow bit 20h.3 ;bit flip-flop for transmit. cpl 2x = 1 full bit time
;config for uart 2: same format
SWRI2 bit 20h.4
serrxslow2 bit 20h.6
SWTI2 bit 20h.5
sertxslow2 bit 20h.7
SWUARTNO bit 21h.0 ;current Software Uart Number
SWRNR bit 21h.1 ;Software Uart Receiver Not Ready
SWTMP equ 0Fh ;Temporary variable to pass indirect address value to register
SBUFR2 equ 0Eh ;Uart 2 received byte value
SBUFR equ 0Dh ;Uart 1 received byte value
SBUFT2 equ 0Ch ;Uart 2 sent byte value
SBUFT equ 0Bh ;Uart 1 sent byte value
swuartint:
;1/2 bit time detected.
;save registers
push PSW
push ACC
;set register bank RS1:RS0 = 1:1 or 1:0 depending on UART wanted
;so we have our own private set of R0-R7 variables for each UART
setb RS1
mov C,SWUARTNO
mov RS0,C
;Get bit from UART 2
mov C,RX2
jb RS0,nour1
mov C,RX1 ;Get bit from UART 1 if RS0 not set
nour1:
jb SWTI,extx
;Transmit routine is only used if transmit complete flag is NOT set.
cpl sertxslow
jnb sertxslow,extx
;Only do the real transmit work on full bit times
;save existing carry flag (it has received value)
push PSW
mov A,R2 ;R2=transmit counter to load
jnz tnz
;Counter=0: Load transmitted value to R3 through temporary variable
mov SWTMP,#R1
mov R3,SWTMP
;Set counter to 1 and clear C to output start bit (of 0)
inc A
clr C
sjmp extx1
tnz:
jnb ACC.3,tne
jnb ACC.0,tne
;Counter is 9 so set transmit complete flag
setb SWTI
clr A ;set counter to 0 and set C to output stop bit (of 1)
setb C
sjmp extx1
tne:
;Counter is between 1 and 8
;Save accumulator to R5 since push/pop wastes cycles
mov R5,A
mov A,R3 ;load accumulator with outgoing data
RRC A ;shift out one byte to C
mov R3,A ;save data
mov A,R5
inc A ;increment count
extx1:
;Use right transmit channel based on chosen UART number
jb RS0,nour2
mov TX1,C
sjmp extx2
nour2:
mov TX2,C
extx2:
;Save count
mov R2,A
;and load back receiver value C
pop PSW
extx:
mov A,R7 ;load receiving count
jnz rnz
;Counter=0. Store ready status
mov SWRNR,C
jc exrx
;increment counter only if start bit=0
inc A
clr serrxslow ;reset flip flop so we wait 1 bit time to get bit.
sjmp exrx
rnz:
cpl serrxslow
jb serrxslow,exrx
;Counter > 0, 1 bit time waited
jnb ACC.3,rne
jnb ACC.0,rne
;Counter = 9. Status = Stop bit. 1=complete. 0=fail.
mov SWRI,C
;Store data
mov SWTMP,R4
mov #R0,SWTMP
;Clear count
clr A
sjmp exrx
rne:
;Counter = 1 to 8.
;Load data same way as transmit routine
mov R6,A
mov A,R4
RRC A
mov R4,A
mov A,R6
inc A ;increment count
exrx:
mov R7,A ;save count to receive count variable
;Don't switch UARTs when in the middle of a bit time
jnb sertxslow,nextuart
;Don't switch UARTs if receiver has data to process
jnb SWRNR,nextuart
;Don't switch UARTs if transmitter has data to process
jnb SWTI,nextuart
;Switch UART
cpl SWUARTNO
;Flip nibbles in configuration as each nibble
;belongs to its own UART
mov A,SWCFG
swap A
mov SWCFG,A
nextuart:
;restore registers and exit
pop ACC
pop PSW
reti
uartcfg:
setb RS1
setb RS0
mov R0,#SBUFR2 ;If RS1=RS0=1, #R0 = contents of SBUFR2
mov R1,#SBUFT2 ;If RS1=RS0=1, #R1 = contents of SBUFT2
clr RS0
mov R0,#SBUFR ;If RS1=1 and RS0=0, #R0 = contents of SBUFR
mov R1,#SBUFT ;If RS1=1 and RS0=0, #R1 = contents of SBUFT
clr RS1 ;Restore register bank (RS1=0, RS0=0)
mov SWCFG,#22h ;Set transmit complete to both UARTs at once
mov TH0,#0A0h ;Value = 256-(((crystal/baud)/12)/2) = 9.6kbps 1/2 bit rate
mov TL0,#0A0h
mov TMOD,#22h ;8-bit timers auto reload
mov SP,#50h ;get stack pointer away from our work
setb TR0 ;enable timer
mov IE,#082h ;enable Timer 0 interrupt
ljmp startapp ;go to program
;serial port 1
;plugged into computer for data testing
RX1 equ P3.0
TX1 equ P3.1
;serial port 2
RX2 equ P3.3
TX2 equ P1.2
startapp:
; Trying to output 'ABCD' or 'abcd' but all I get is 'DDDD'
mov SBUFT,#0h ;Set character for UART 1
clr SWTI ;clear complete flag
jnb SWTI,$ ;stall until character transmitted
mov SBUFT,#'A' ;repeat...
clr SWTI
jnb SWTI,$
mov SBUFT,#'B'
clr SWTI
jnb SWTI,$
mov SBUFT,#'C'
clr SWTI
jnb SWTI,$
mov SBUFT,#'D'
clr SWTI
jnb SWTI,$
mov SBUFT2,#0h ;Set character for UART 2
clr SWTI2 ;clear complete flag
jnb SWTI2,$ ;stall until character transmitted
mov SBUFT2,#'a' ;repeat...
clr SWTI2
jnb SWTI2,$
mov SBUFT2,#'b'
clr SWTI2
jnb SWTI2,$
mov SBUFT2,#'c'
clr SWTI2
jnb SWTI2,$
mov SBUFT2,#'d'
clr SWTI2
jnb SWTI2,$
sjmp $
I'm trying hard to study Assembly language.
I really need help to store different 10 items in an array
I want to build a program that will accept items from 10 choices and it will store it.
Those 10 items have different value.
Example
Item 1 = 10$
Item 2 = 4$
So that when the User tries to choose Item1 and Item2 it will show the
sum of both items.
I'll be gladly be happy if someone can share his/her own code that can store 10 items with the sum of all items. Thanks
Here's my code:
_start:
mov eax,3 ;number bytes to be summed
mov ebx,0 ;EBX will store the sum
mov ecx, x ;ECX will point to the current element to be summed
top: add ebx, [ecx]
add ecx,1 ;move pointer to next element
dec eax ;decrement counter
jnz top ;if counter not 0, then loop again
done:
add ebx, '0'
mov [sum], ebx ;done, store result in "sum"
display:
mov edx,1 ;message length
mov ecx, sum ;message to write
mov ebx, 1 ;file descriptor (stdout)
mov eax, 4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax, 1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
global x
x:
db 2
db 4
db 3
sum:
db 0
My code here does have problem.
x:
db 2
db 4
db 3
sum:
db 0
Since you've defined all of your variables to be of byte type, you must process them as bytes! You're reading and writing dwords in your program.
This could have been OK:
top: add bl, [ecx]
add ecx, 1 ;move pointer to next element
dec eax ;decrement counter
jnz top ;if counter not 0, then loop again
done:
add bl, '0'
mov [sum], bl ;done, store result in "sum"