Cx 레지스터를 변수 값으로 초기화 할 수 있습니까? '아니오'라면, 방법 동적 사용자 입력 값 CX를 초기화 할 경우명세서 작업을 완벽하게 만드는 방법은 무엇입니까?
MOV Cx, varaible
아래 도시 같은? 도와주세요!
Cx 레지스터를 변수 값으로 초기화 할 수 있습니까? '아니오'라면, 방법 동적 사용자 입력 값 CX를 초기화 할 경우명세서 작업을 완벽하게 만드는 방법은 무엇입니까?
MOV Cx, varaible
아래 도시 같은? 도와주세요!
이름이 아니라 정신적 인 이미지입니다. 어셈블리에는 변수가 없습니다.
기계에는 레지스터, 메모리, 주소 및 명령어로 메모리 액세스가 있습니다. 변수은 프로그래머의 논리적 구조로, 코드를 이와 같이 작성하기로 결정하여 메모리를 "가변적"으로 사용합니다. 그러나 그가 실수하지 않거나 실수를 저 지르면 변수가 변하지 않으므로 기계는 신경 쓰지 않습니다. 코드에서 예를 들어
, 당신은.data
절에서 "변수"에 대한 메모리를 할당이 효율적으로 메모리에 주소 기호
var
로 변환합니다
.Data
var DB ?
. 또한 .data
섹션에서 1 바이트를 예약하므로 다음에 거기에 착륙하도록 정의 된 모든 것이 그 후에 할당됩니다. 다음 줄에 var2 DB 13
을 추가하면 var2
주소는 var + 1
과 같습니다. 당신은 또한 같은, 동일한 주소로 여러 심볼을 만들 수 있습니다
.Data
var:
var2:
DB ?
을 모두 var
및 var2
기호는 동일한 메모리 주소를 가리 같은 정의와 함께.
:
MOV [var], AL ; store value in AL into memory at address "var"
; your MOV var, AL without brackets works only in MASM/TASM assemblers
; but it is not valid Intel syntax, I will use brackets for every memory access
이것은에서 8 비트 값을 기록 어드레스 var
에서 메모리로 AL
. 여태까지는 그런대로 잘됐다. 이제 다음에 대해 묻습니다.
MOV CX, [var]
이 내용은 컴파일되고 실행되지만 예상대로 작동하지 않습니다. 메모리에 8 비트 만 쓰고 var
은 1 바이트 만 예약했기 때문입니다. 그러나 CX
은 16 비트 레지스터입니다 (상위 8 비트는 CH
이고 하위 8 비트는 CL
). 따라서이 명령어는 주소 var
의 메모리에서 2 바이트를 읽습니다. x86은 리틀 엔디안이므로 CPU가 16 비트 값으로 작동하면 하위 8 비트를 첫 번째 바이트 (오프셋 +0)로 매핑하고 상위 8 비트는 두 번째 바이트 (오프셋 +1)로 매핑합니다. 따라서 AL
에서 저장된 값으로 CL
을로드하고 var
이후에 메모리에있는 어떤 값으로 CH
을로드합니다. var
뒤에 var2 DB 13
을 추가하는 경우 CH
은 13
과 같으므로 총 CX
값은 13*256 + <stored_AL>
이됩니다. AL
이 저장된 경우 CX = 3335
(또는 16 진수 형식 인 0D07h
)은 D
= 13, 7
= 7이라는 두 바이트 값을 잘 나타냅니다.
저장된 8 비트 값을 CX
으로 올바르게 읽으려면 8 비트에서 16 비트로 확장해야합니다.당신이 80386+ 명령어 세트와 함께 작업하는 경우, 특별한 지시가 거기에 있습니다 : 당신은 같은 값을 계산해야
MOVZX cx,BYTE PTR [var] ; zero-extend value ("unsigned" arithmetic)
MOVSX cx,BYTE PTR [var] ; sign-extend value ("signed" arithmetic)
80386 전에, 하나의 가능한 방법은 다음과 같습니다
XOR cx, cx ; clear all 16bits of CX to zero
MOV cl, [var] ; fetch only low 8 bits from memory
; CX is now zero-extended 16 bit value of [var] (like MOVZX)
MOV ch, [var] ; fetch 8 bit value into upper 8 bits of CX
SAR cx, 8 ; use right shift by 8 bits to sign-extend the value
; CX is now sign-extended 16 bit value of [var] (like MOVSX)
; this code is not optimal on 586+ CPUs, but then use MOVSX
그래서 그 주요이다 "just memory"와 "variables"의 차이점은 어셈블리가 당신을 보호하지 않으며, 변수 밖에서 메모리를 읽고 쓸 수있게 해줄 것입니다. 올바른 코드를 작성하고 데이터 크기를 생각하고 충분히 할당/예약하십시오 기억. 또한 수동으로 모든 포인터 연산을 수행합니다. 즉, 단어 배열 (16 비트 값)을 만들려면 정확한 바이트 주소를 계산하려면 * 2로 인덱스를 조정해야합니다 (C/C++에서는 포인터 계산을 숨길 것입니다. 당신은 단지 [i]를 수행하고, * 2는 컴파일러에 의해 내부적으로 수행됩니다).
저는 컴파일러의 방식과 같은 변수를 특정 위치에 묶이지 않은 논리적 엔티티라고 생각합니다. 따라서 변수는 함수의 일부 부분에서는 레지스터에 있고 다른 부분에서는 메모리에있을 수 있습니다. 정말 레이블이있는 정적 저장소를 설명하기 위해 "변수"만 사용한다는 일반적인 asm 용어를 싫어합니다. 따라서 레지스터에 변수를 저장하는 것에 대해 이야기하지는 않더라도 +1에 대해 논쟁하십시오. –
"변수 값"변수에 대한 정의를 표시하십시오. "사용자 입력 값"이 변수를 어떻게 입력합니까? –
어셈블리 언어 또는 인라인 어셈블리 언어에 대해 이야기하고 있습니까? –
선생님 다음 코드를 가지고 있습니다 . 데이터 var DB? 내부 및 내부 PRO MOV 아, 01 INT 21H ; 그런 다음 변수를 Al 레지스터에서 var로 명명 된 변수로 이동했습니다. MOV var, Al ; 그렇다면 나는 다음과 같이 cx를 초기화했습니다 MOV Cx, var – Tania